Skip to content

Commit

Permalink
TypeCompiler Return Type Annotation (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 authored Jun 22, 2023
1 parent 772e566 commit 28d0f33
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 14 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@sinclair/typebox",
"version": "0.28.17",
"version": "0.28.18",
"description": "JSONSchema Type Builder with Static Type Resolution for TypeScript",
"keywords": [
"typescript",
Expand Down
27 changes: 16 additions & 11 deletions src/compiler/compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export class TypeCompilerTypeGuardError extends Error {
}

export interface TypeCompilerOptions {
language: 'typescript' | 'javascript'
language?: 'typescript' | 'javascript'
}
/** Compiles Types for Runtime Type Checking */
export namespace TypeCompiler {
Expand Down Expand Up @@ -185,7 +185,7 @@ export namespace TypeCompiler {
if (IsNumber(schema.maxItems)) yield `${value}.length <= ${schema.maxItems}`
if (schema.uniqueItems === true) yield `((function() { const set = new Set(); for(const element of ${value}) { const hashed = hash(element); if(set.has(hashed)) { return false } else { set.add(hashed) } } return true })())`
const expression = CreateExpression(schema.items, references, 'value')
const parameter = CreateParameter('value')
const parameter = CreateParameter('value', 'any')
yield `${value}.every((${parameter}) => ${expression})`
}
function* BigInt(schema: Types.TBigInt, references: Types.TSchema[], value: string): IterableIterator<string> {
Expand Down Expand Up @@ -461,20 +461,24 @@ export namespace TypeCompiler {
functions: new Set<string>(), // local functions
customs: new Map<string, unknown>(), // custom type data
}
function CreateExpression(schema: Types.TSchema, references: Types.TSchema[], value: string): string {
return `(${[...Visit(schema, references, value)].join(' && ')})`
}
function CreateFunctionName($id: string) {
return `check_${Identifier.Encode($id)}`
}
function CreateParameter(name: string) {
const annotation = state.language === 'typescript' ? ': any' : ''
function CreateExpression(schema: Types.TSchema, references: Types.TSchema[], value: string): string {
return `(${[...Visit(schema, references, value)].join(' && ')})`
}
function CreateParameter(name: string, type: string) {
const annotation = state.language === 'typescript' ? `: ${type}` : ''
return `${name}${annotation}`
}
function CreateReturns(type: string) {
return state.language === 'typescript' ? `: ${type}` : ''
}
function CreateFunction(name: string, schema: Types.TSchema, references: Types.TSchema[], value: string): string {
const expression = [...Visit(schema, references, value, true)].map((condition) => ` ${condition}`).join(' &&\n')
const parameter = CreateParameter('value')
return `function ${name}(${parameter}) {\n return (\n${expression}\n )\n}`
const parameter = CreateParameter('value', 'any')
const returns = CreateReturns('boolean')
return `function ${name}(${parameter})${returns} {\n return (\n${expression}\n )\n}`
}
function PushFunction(functionBody: string) {
state.variables.add(functionBody)
Expand All @@ -493,10 +497,11 @@ export namespace TypeCompiler {
function Build<T extends Types.TSchema>(schema: T, references: Types.TSchema[]): string {
const check = CreateFunction('check', schema, references, 'value') // interior visit
const locals = GetLocals()
const parameter = CreateParameter('value')
const parameter = CreateParameter('value', 'any')
const returns = CreateReturns('boolean')
// prettier-ignore
return IsString(schema.$id) // ensure top level schemas with $id's are hoisted
? `${locals.join('\n')}\nreturn function check(${parameter}) {\n return ${CreateFunctionName(schema.$id)}(value)\n}`
? `${locals.join('\n')}\nreturn function check(${parameter})${returns} {\n return ${CreateFunctionName(schema.$id)}(value)\n}`
: `${locals.join('\n')}\nreturn ${check}`
}
/** Returns the generated assertion code used to validate this type. */
Expand Down

0 comments on commit 28d0f33

Please sign in to comment.