diff --git a/changelog/0.34.0.md b/changelog/0.34.0.md index 703528ec..6aa605bb 100644 --- a/changelog/0.34.0.md +++ b/changelog/0.34.0.md @@ -1,4 +1,6 @@ ### 0.34.0 +- [Revision 0.34.16](https://github.com/sinclairzx81/typebox/pull/1155) + - Export the TypeBox Parsing Infrastructure - [Revision 0.34.15](https://github.com/sinclairzx81/typebox/pull/1148) - [1147](https://github.com/sinclairzx81/typebox/issues/1147) Fix incorrect truncation for integers that exceed 32-bit values in Value.Convert - [Revision 0.34.14](https://github.com/sinclairzx81/typebox/pull/1140) diff --git a/example/index.ts b/example/index.ts index 9d228684..ff155a02 100644 --- a/example/index.ts +++ b/example/index.ts @@ -1,8 +1,8 @@ import { TypeSystem } from '@sinclair/typebox/system' import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value, ValuePointer } from '@sinclair/typebox/value' -import { Parse, StaticParseAsType } from '@sinclair/typebox/syntax' import { Type, TypeGuard, Kind, Static, TSchema } from '@sinclair/typebox' +import { Syntax } from '@sinclair/typebox/syntax' // ----------------------------------------------------------- // Create: Type @@ -22,7 +22,7 @@ console.log(T) // Parse: Type // ----------------------------------------------------------- -const S = Parse({ T }, `{ x: T, y: T, z: T }`) +const S = Syntax({ T }, `{ x: T, y: T, z: T }`) type S = Static diff --git a/package-lock.json b/package-lock.json index b2abe8da..3b2d11d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@sinclair/typebox", - "version": "0.34.15", + "version": "0.34.16", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@sinclair/typebox", - "version": "0.34.15", + "version": "0.34.16", "license": "MIT", "devDependencies": { "@arethetypeswrong/cli": "^0.13.2", diff --git a/package.json b/package.json index 734199b7..455df4bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@sinclair/typebox", - "version": "0.34.15", + "version": "0.34.16", "description": "Json Schema Type Builder with Static Type Resolution for TypeScript", "keywords": [ "typescript", diff --git a/readme.md b/readme.md index b33def23..37fd0b36 100644 --- a/readme.md +++ b/readme.md @@ -77,10 +77,6 @@ License MIT - [Transform](#types-transform) - [Guard](#types-guard) - [Unsafe](#types-unsafe) -- [Syntax](#syntax) - - [Parse](#syntax-parse) - - [Static](#syntax-static) - - [Limits](#syntax-limits) - [Values](#values) - [Assert](#values-assert) - [Create](#values-create) @@ -100,6 +96,11 @@ License MIT - [Errors](#values-errors) - [Mutate](#values-mutate) - [Pointer](#values-pointer) +- [Syntax](#syntax) + - [Type](#syntax-type) + - [Options](#syntax-options) + - [Parameters](#syntax-parameters) + - [Generics](#syntax-generics) - [TypeRegistry](#typeregistry) - [Type](#typeregistry-type) - [Format](#typeregistry-format) @@ -1044,162 +1045,6 @@ if(TypeGuard.IsString(T)) { } ``` - - -## Syntax Types - -TypeBox has support for parsing TypeScript type annotations directly into TypeBox types. This feature supports both runtime and static parsing, with TypeBox implementing TypeScript parsers within the TypeScript type system itself. Syntax Types use the TypeBox Json Schema representations as an AST target for TypeScript types, providing a direct mapping between TypeScript syntax and Json Schema. Syntax Types are offered as a syntactical frontend to the Standard Type Builder API. - -This feature is available via optional import. - -```typescript -import { Parse } from '@sinclair/typebox/syntax' -``` - - - -### Parse - -Use the Parse function to transform a TypeScript type annotation into a TypeBox type. This function will return the parsed TypeBox type or undefined on error. - -```typescript -const A = Parse('string') // const A: TString - -const B = Parse('[1, 2, 3]') // const B: TTuple<[ - // TLiteral<1>, - // TLiteral<2>, - // TLiteral<3> - // ]> - -const C = Parse(`{ x: number, y: number }`) // const C: TObject<{ - // x: TNumber - // y: TNumber - // }> -``` - -Syntax Types can compose with Standard Types created via the Type Builder API - -```typescript -const T = Type.Object({ // const T: TObject<{ - x: Parse('number'), // x: TNumber, - y: Parse('string'), // y: TString, - z: Parse('boolean') // z: TBoolean -}) // }> -``` - -Standard Types can also be passed to and referenced within Syntax Types. - -```typescript -const X = Type.Number() -const Y = Type.String() -const Z = Type.Boolean() - -const T = Parse({ X, Y, Z }, `{ - x: X, - y: Y, - z: Z -}`) -``` - -Syntax Types also support Module parsing. - -```typescript -const Foo = Parse(`module Foo { - - export type PartialUser = Pick & Partial> - - export interface User { - id: string - name: string - email: string - } - -}`) - -const PartialUser = Foo.Import('PartialUser') // TImport<{...}, 'PartialUser'> - -type PartialUser = Static // type PartialUser = { - // id: string, - // } & { - // name?: string, - // email?: string, - // } -``` - - - -### Static - -Syntax Types provide two Static types specific to inferring TypeBox and TypeScript types from strings. - -```typescript -import { StaticParseAsSchema, StaticParseAsType } from '@sinclair/typebox/syntax' - -// Will infer as a TSchema - -type S = StaticParseAsSchema<{}, '{ x: number }'> // type S: TObject<{ - // x: TNumber - // }> - -// Will infer as a type - -type T = StaticParseAsType<{}, '{ x: number }'> // type T = { - // x: number - // } -``` - - - - -### Limitations - -TypeBox parses TypeScript types directly within the TypeScript type system. This process does come with an inference cost, which scales with the size and complexity of the types being parsed. Although TypeBox strives to optimize Syntax Types, users should be aware of the following structures: - -```typescript -// Excessively wide structures will result in instantiation limits exceeding -const A = Parse(`[ - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, -]`) - -// Excessively nested structures will result in instantiation limits exceeding -const B = Parse(`{ - x: { - y: { - z: { - w: 1 <-- Type instantiation is excessively deep and possibly infinite. - } - } - } -}`) -``` - -If Syntax Types exceed TypeScript's instantiation limits, users are advised to fall back to the Standard Type Builder API. Alternatively, TypeBox offers a `ParseOnly` function that parses the TypeScript syntax at runtime without statically inferring the schema. - -```typescript -import { ParseOnly } from '@sinclair/typebox/syntax' - -// const A: TSchema | undefined - -const A = ParseOnly(`{ - x: { - y: { - z: { - w: 1 - } - } - } -}`) -``` - -For more information on static parsing, refer to the [ParseBox](https://github.com/sinclairzx81/parsebox) project. - ## Values @@ -1490,6 +1335,87 @@ ValuePointer.Set(A, '/y', 1) // A' = { x: 1, y: 1, z: 0 ValuePointer.Set(A, '/z', 1) // A' = { x: 1, y: 1, z: 1 } ``` + + + + +## Syntax Types + +TypeBox provides optional support for runtime and type level parsing from TypeScript syntax. + +```typescript +import { Syntax } from '@sinclair/typebox/syntax' +``` + + + +### Type + +Use the Syntax function to create TypeBox type from TypeScript syntax. + +```typescript +const T = Syntax(`{ x: number, y: number }`) // const T: TObject<{ + // x: TNumber + // y: TNumber + // }> +``` + + + +### Options + +Options can be passed to types on the last parameter + +```typescript +const T = Syntax(`number`, { // const T = { + minimum: 0, // type: 'number', + maximum: 10 // minimum: 0, +}) // maximum: 10 + // } +``` + + + +### Parameters + +Syntax types can be parameterized to accept exterior types. + +```typescript +const T = Syntax('number') + +const S = Syntax({ T }, `{ x: T, y: T, z: T }`) // const S: TObject<{ + // x: TNumber, + // y: TNumber, + // z: TNumber + // }> +``` + + + +### Generics + +Generic syntax types can be created using parameterized types. + +```typescript +// Generic Syntax Type + +const Vector = (T: T) => Syntax({ T: Syntax(T) }, `{ + x: T, + y: T, + z: T +}`) + + +// Instanced Generic Syntax Type + +const NumberVector = Vector('number') // const NumberVector: TObject<{ + // x: TNumber, + // y: TNumber, + // z: TNumber + // }> +``` + + ## TypeRegistry diff --git a/src/syntax/parsebox/index.ts b/src/parser/index.ts similarity index 100% rename from src/syntax/parsebox/index.ts rename to src/parser/index.ts diff --git a/src/syntax/parsebox/runtime/guard.ts b/src/parser/runtime/guard.ts similarity index 100% rename from src/syntax/parsebox/runtime/guard.ts rename to src/parser/runtime/guard.ts diff --git a/src/syntax/parsebox/runtime/index.ts b/src/parser/runtime/index.ts similarity index 100% rename from src/syntax/parsebox/runtime/index.ts rename to src/parser/runtime/index.ts diff --git a/src/syntax/parsebox/runtime/module.ts b/src/parser/runtime/module.ts similarity index 100% rename from src/syntax/parsebox/runtime/module.ts rename to src/parser/runtime/module.ts diff --git a/src/syntax/parsebox/runtime/parse.ts b/src/parser/runtime/parse.ts similarity index 100% rename from src/syntax/parsebox/runtime/parse.ts rename to src/parser/runtime/parse.ts diff --git a/src/syntax/parsebox/runtime/token.ts b/src/parser/runtime/token.ts similarity index 100% rename from src/syntax/parsebox/runtime/token.ts rename to src/parser/runtime/token.ts diff --git a/src/syntax/parsebox/runtime/types.ts b/src/parser/runtime/types.ts similarity index 100% rename from src/syntax/parsebox/runtime/types.ts rename to src/parser/runtime/types.ts diff --git a/src/syntax/parsebox/static/index.ts b/src/parser/static/index.ts similarity index 100% rename from src/syntax/parsebox/static/index.ts rename to src/parser/static/index.ts diff --git a/src/syntax/parsebox/static/parse.ts b/src/parser/static/parse.ts similarity index 100% rename from src/syntax/parsebox/static/parse.ts rename to src/parser/static/parse.ts diff --git a/src/syntax/parsebox/static/token.ts b/src/parser/static/token.ts similarity index 100% rename from src/syntax/parsebox/static/token.ts rename to src/parser/static/token.ts diff --git a/src/syntax/parsebox/static/types.ts b/src/parser/static/types.ts similarity index 100% rename from src/syntax/parsebox/static/types.ts rename to src/parser/static/types.ts diff --git a/src/syntax/index.ts b/src/syntax/index.ts index 8a2445bf..d7fc819f 100644 --- a/src/syntax/index.ts +++ b/src/syntax/index.ts @@ -26,4 +26,4 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -export * from './parse' +export * from './syntax' diff --git a/src/syntax/runtime.ts b/src/syntax/runtime.ts index 2f5801f2..8a62f201 100644 --- a/src/syntax/runtime.ts +++ b/src/syntax/runtime.ts @@ -26,8 +26,8 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { Runtime } from './parsebox/index' -import * as Types from '../type/index' +import { Runtime } from '../parser/index' +import * as t from '../type/index' // ------------------------------------------------------------------ // Tokens @@ -62,164 +62,40 @@ function DestructureRight(values: T[]): [T[], T | undefined] { // ------------------------------------------------------------------ // Deref // ------------------------------------------------------------------ -const Deref = (context: Types.TProperties, key: string): Types.TSchema => { - return key in context ? context[key] : Types.Ref(key) +const Deref = (context: t.TProperties, key: string): t.TSchema => { + return key in context ? context[key] : t.Ref(key) } // ------------------------------------------------------------------ -// ExportModifier -// ------------------------------------------------------------------ -// prettier-ignore -const ExportModifierMapping = (values: unknown[]) => { - return values.length === 1 -} -// prettier-ignore -const ExportModifier = Runtime.Union([ - Runtime.Tuple([Runtime.Const('export')]), Runtime.Tuple([]) -], ExportModifierMapping) - -// ------------------------------------------------------------------ -// TypeAliasDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -const TypeAliasDeclarationMapping = (_Export: boolean, _Keyword: 'type', Ident: string, _Equals: typeof Equals, Type: Types.TSchema) => { - return { [Ident]: Type } -} -// prettier-ignore -const TypeAliasDeclaration = Runtime.Tuple([ - Runtime.Ref('ExportModifier'), - Runtime.Const('type'), - Runtime.Ident(), - Runtime.Const(Equals), - Runtime.Ref('Type') -], value => TypeAliasDeclarationMapping(...value)) - -// ------------------------------------------------------------------ -// HeritageList -// ------------------------------------------------------------------ -// prettier-ignore (note, heritage list should disallow trailing comma) -const HeritageListDelimiter = Runtime.Union([Runtime.Tuple([Runtime.Const(Comma), Runtime.Const(Newline)]), Runtime.Tuple([Runtime.Const(Comma)])]) -// prettier-ignore -const HeritageListMapping = (values: string[], context: Types.TProperties): Types.TSchema[] => { - return ( - values.length === 3 ? [Deref(context, values[0]), ...values[2] as never] : - values.length === 1 ? [Deref(context, values[0])] : - [] - ) as never -} -// prettier-ignore -const HeritageList = Runtime.Union([ - Runtime.Tuple([Runtime.Ident(), HeritageListDelimiter, Runtime.Ref('HeritageList')]), - Runtime.Tuple([Runtime.Ident()]), - Runtime.Tuple([]) -], HeritageListMapping) -// ------------------------------------------------------------------ -// Heritage -// ------------------------------------------------------------------ -// prettier-ignore -const HeritageMapping = (values: unknown[]): unknown[] => { - return (values.length === 2 ? values[1] : []) as never -} -// prettier-ignore -const Heritage = Runtime.Union([ - Runtime.Tuple([Runtime.Const('extends'), Runtime.Ref('HeritageList')]), - Runtime.Tuple([]) -], HeritageMapping) -// ------------------------------------------------------------------ -// InterfaceDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -const InterfaceDeclarationMapping = (_0: boolean, _1: 'interface', Ident: string, Heritage: Types.TRef[], _4: typeof LBrace, Properties: Types.TProperties, _6: typeof RBrace) => { - return { [Ident]: Types.Intersect([...Heritage, Types.Object(Properties)]) } -} -// prettier-ignore -const InterfaceDeclaration = Runtime.Tuple([ - Runtime.Ref('ExportModifier'), - Runtime.Const('interface'), - Runtime.Ident(), - Runtime.Ref('Heritage'), - Runtime.Const(LBrace), - Runtime.Ref('Properties'), - Runtime.Const(RBrace), -], values => InterfaceDeclarationMapping(...values)) - -// ------------------------------------------------------------------ -// ModuleType -// ------------------------------------------------------------------ -// prettier-ignore -const ModuleType = Runtime.Union([ - Runtime.Ref('InterfaceDeclaration'), - Runtime.Ref('TypeAliasDeclaration') -]) -// ------------------------------------------------------------------ -// ModuleProperties -// ------------------------------------------------------------------ -// prettier-ignore -const ModulePropertiesDelimiter = Runtime.Union([ - Runtime.Tuple([Runtime.Const(SemiColon), Runtime.Const(Newline)]), - Runtime.Tuple([Runtime.Const(SemiColon)]), - Runtime.Tuple([Runtime.Const(Newline)]), -]) -// prettier-ignore -const ModulePropertiesMapping = (values: unknown[]): Types.TProperties => { - return ( - values.length === 3 ? { ...values[0] as Types.TProperties, ...values[2] as Types.TProperties }: - values.length === 1 ? values[0] as Types.TProperties : - {} as Types.TProperties - ) -} -// prettier-ignore -const ModuleProperties = Runtime.Union([ - Runtime.Tuple([Runtime.Ref('ModuleType'), ModulePropertiesDelimiter, Runtime.Ref('ModuleProperties')]), - Runtime.Tuple([Runtime.Ref('ModuleType')]), - Runtime.Tuple([]), -], ModulePropertiesMapping) -// ------------------------------------------------------------------ -// ModuleDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -const ModuleIdentifier = Runtime.Union([ - Runtime.Tuple([Runtime.Ident()]), - Runtime.Tuple([]) -]) -// prettier-ignore -const ModuleDeclarationMapping = (_1: boolean, _2: 'module', _Ident: string[], _3: typeof LBrace, Properties: Types.TProperties, _5: typeof RBrace) => { - return Types.Module(Properties) -} -// prettier-ignore -const ModuleDeclaration = Runtime.Tuple([ - Runtime.Ref('ExportModifier'), Runtime.Const('module'), ModuleIdentifier, Runtime.Const(LBrace), Runtime.Ref('ModuleProperties'), Runtime.Const(RBrace) -], values => ModuleDeclarationMapping(...values)) -// ------------------------------------------------------------------ // Reference // ------------------------------------------------------------------ // prettier-ignore -const Reference = Runtime.Ident((value, context: Types.TProperties) => Deref(context, value)) +const Reference = Runtime.Ident((value, context: t.TProperties) => Deref(context, value)) // ------------------------------------------------------------------ // Literal // ------------------------------------------------------------------ // prettier-ignore const Literal = Runtime.Union([ - Runtime.Union([Runtime.Const('true'), Runtime.Const('false')], value => Types.Literal(value === 'true')), - Runtime.Number(value => Types.Literal(parseFloat(value))), - Runtime.String([SingleQuote, DoubleQuote, Tilde], value => Types.Literal(value)) + Runtime.Union([Runtime.Const('true'), Runtime.Const('false')], value => t.Literal(value === 'true')), + Runtime.Number(value => t.Literal(parseFloat(value))), + Runtime.String([SingleQuote, DoubleQuote, Tilde], value => t.Literal(value)) ]) // ------------------------------------------------------------------ // Keyword // ------------------------------------------------------------------ // prettier-ignore const Keyword = Runtime.Union([ - Runtime.Const('any', Runtime.As(Types.Any())), - Runtime.Const('bigint', Runtime.As(Types.BigInt())), - Runtime.Const('boolean', Runtime.As(Types.Boolean())), - Runtime.Const('integer', Runtime.As(Types.Integer())), - Runtime.Const('never', Runtime.As(Types.Never())), - Runtime.Const('null', Runtime.As(Types.Null())), - Runtime.Const('number', Runtime.As(Types.Number())), - Runtime.Const('string', Runtime.As(Types.String())), - Runtime.Const('symbol', Runtime.As(Types.Symbol())), - Runtime.Const('undefined', Runtime.As(Types.Undefined())), - Runtime.Const('unknown', Runtime.As(Types.Unknown())), - Runtime.Const('void', Runtime.As(Types.Void())), + Runtime.Const('any', Runtime.As(t.Any())), + Runtime.Const('bigint', Runtime.As(t.BigInt())), + Runtime.Const('boolean', Runtime.As(t.Boolean())), + Runtime.Const('integer', Runtime.As(t.Integer())), + Runtime.Const('never', Runtime.As(t.Never())), + Runtime.Const('null', Runtime.As(t.Null())), + Runtime.Const('number', Runtime.As(t.Number())), + Runtime.Const('string', Runtime.As(t.String())), + Runtime.Const('symbol', Runtime.As(t.Symbol())), + Runtime.Const('undefined', Runtime.As(t.Undefined())), + Runtime.Const('unknown', Runtime.As(t.Unknown())), + Runtime.Const('void', Runtime.As(t.Void())), ]) // ------------------------------------------------------------------ // KeyOf @@ -314,54 +190,54 @@ const Base = Runtime.Union([ // Factor // ------------------------------------------------------------------ // prettier-ignore -const FactorExtends = (Type: Types.TSchema, Extends: Types.TSchema[]) => { +const FactorExtends = (Type: t.TSchema, Extends: t.TSchema[]) => { return Extends.length === 3 - ? Types.Extends(Type, Extends[0], Extends[1], Extends[2]) + ? t.Extends(Type, Extends[0], Extends[1], Extends[2]) : Type } // prettier-ignore -const FactorIndexArray = (Type: Types.TSchema, IndexArray: unknown[]): Types.TSchema => { - const [Left, Right] = DestructureRight(IndexArray) as [unknown[], Types.TSchema[]] +const FactorIndexArray = (Type: t.TSchema, IndexArray: unknown[]): t.TSchema => { + const [Left, Right] = DestructureRight(IndexArray) as [unknown[], t.TSchema[]] return ( - !Types.ValueGuard.IsUndefined(Right) ? ( + !t.ValueGuard.IsUndefined(Right) ? ( // note: Indexed types require reimplementation to replace `[number]` indexers - Right.length === 1 ? Types.Index(FactorIndexArray(Type, Left), Right[0]) as never : - Right.length === 0 ? Types.Array(FactorIndexArray(Type, Left)) : - Types.Never() + Right.length === 1 ? t.Index(FactorIndexArray(Type, Left), Right[0]) as never : + Right.length === 0 ? t.Array(FactorIndexArray(Type, Left)) : + t.Never() ) : Type ) } // prettier-ignore -const FactorMapping = (KeyOf: boolean, Type: Types.TSchema, IndexArray: unknown[], Extends: Types.TSchema[]) => { +const FactorMapping = (KeyOf: boolean, Type: t.TSchema, IndexArray: unknown[], Extends: t.TSchema[]) => { return KeyOf - ? FactorExtends(Types.KeyOf(FactorIndexArray(Type, IndexArray)), Extends) + ? FactorExtends(t.KeyOf(FactorIndexArray(Type, IndexArray)), Extends) : FactorExtends(FactorIndexArray(Type, IndexArray), Extends) } // prettier-ignore const Factor = Runtime.Tuple([ Runtime.Ref('KeyOf'), - Runtime.Ref('Base'), + Runtime.Ref('Base'), Runtime.Ref('IndexArray'), - Runtime.Ref('Extends') + Runtime.Ref('Extends') ], values => FactorMapping(...values)) // ------------------------------------------------------------------ // Expr // ------------------------------------------------------------------ // prettier-ignore -function ExprBinaryMapping(Left: Types.TSchema, Rest: unknown[]): Types.TSchema { +function ExprBinaryMapping(Left: t.TSchema, Rest: unknown[]): t.TSchema { return ( Rest.length === 3 ? (() => { - const [Operator, Right, Next] = Rest as [string, Types.TSchema, unknown[]] + const [Operator, Right, Next] = Rest as [string, t.TSchema, unknown[]] const Schema = ExprBinaryMapping(Right, Next) if (Operator === '&') { - return Types.TypeGuard.IsIntersect(Schema) - ? Types.Intersect([Left, ...Schema.allOf]) - : Types.Intersect([Left, Schema]) + return t.TypeGuard.IsIntersect(Schema) + ? t.Intersect([Left, ...Schema.allOf]) + : t.Intersect([Left, Schema]) } if (Operator === '|') { - return Types.TypeGuard.IsUnion(Schema) - ? Types.Union([Left, ...Schema.anyOf]) - : Types.Union([Left, Schema]) + return t.TypeGuard.IsUnion(Schema) + ? t.Union([Left, ...Schema.anyOf]) + : t.Union([Left, Schema]) } throw 1 })() : Left @@ -374,7 +250,7 @@ const ExprTermTail = Runtime.Union([ ]) // prettier-ignore const ExprTerm = Runtime.Tuple([ - Runtime.Ref('Factor'), Runtime.Ref('ExprTermTail') + Runtime.Ref('Factor'), Runtime.Ref('ExprTermTail') ], value => ExprBinaryMapping(...value)) // prettier-ignore const ExprTail = Runtime.Union([ @@ -383,7 +259,7 @@ const ExprTail = Runtime.Union([ ]) // prettier-ignore const Expr = Runtime.Tuple([ - Runtime.Ref('ExprTerm'), Runtime.Ref('ExprTail') + Runtime.Ref('ExprTerm'), Runtime.Ref('ExprTail') ], value => ExprBinaryMapping(...value)) // ------------------------------------------------------------------ @@ -397,11 +273,11 @@ const PropertyKey = Runtime.Union([Runtime.Ident(), Runtime.String([SingleQuote, const Readonly = Runtime.Union([Runtime.Tuple([Runtime.Const('readonly')]), Runtime.Tuple([])], (value) => value.length > 0) const Optional = Runtime.Union([Runtime.Tuple([Runtime.Const(Question)]), Runtime.Tuple([])], (value) => value.length > 0) // prettier-ignore -const PropertyMapping = (IsReadonly: boolean, Key: string, IsOptional: boolean, _: typeof Colon, Type: Types.TSchema) => ({ +const PropertyMapping = (IsReadonly: boolean, Key: string, IsOptional: boolean, _: typeof Colon, Type: t.TSchema) => ({ [Key]: ( - IsReadonly && IsOptional ? Types.ReadonlyOptional(Type) : - IsReadonly && !IsOptional ? Types.Readonly(Type) : - !IsReadonly && IsOptional ? Types.Optional(Type) : + IsReadonly && IsOptional ? t.ReadonlyOptional(Type) : + IsReadonly && !IsOptional ? t.Readonly(Type) : + !IsReadonly && IsOptional ? t.Optional(Type) : Type ) }) @@ -411,7 +287,7 @@ const Property = Runtime.Tuple([ Runtime.Ref('PropertyKey'), Runtime.Ref('Optional'), Runtime.Const(Colon), - Runtime.Ref('Type'), + Runtime.Ref('Type'), ], value => PropertyMapping(...value)) // prettier-ignore const PropertyDelimiter = Runtime.Union([ @@ -423,9 +299,9 @@ const PropertyDelimiter = Runtime.Union([ ]) // prettier-ignore const Properties = Runtime.Union([ - Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter'), Runtime.Ref('Properties')]), - Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter')]), - Runtime.Tuple([Runtime.Ref('Property')]), + Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter'), Runtime.Ref('Properties')]), + Runtime.Tuple([Runtime.Ref('Property'), Runtime.Ref('PropertyDelimiter')]), + Runtime.Tuple([Runtime.Ref('Property')]), Runtime.Tuple([]) ], values => ( values.length === 3 ? { ...values[0], ...values[2] } : @@ -437,11 +313,11 @@ const Properties = Runtime.Union([ // Object // ------------------------------------------------------------------ // prettier-ignore -const ObjectMapping = (_0: typeof LBrace, Properties: Types.TProperties, _2: typeof RBrace) => Types.Object(Properties) +const ObjectMapping = (_0: typeof LBrace, Properties: t.TProperties, _2: typeof RBrace) => t.Object(Properties) // prettier-ignore const _Object = Runtime.Tuple([ Runtime.Const(LBrace), - Runtime.Ref('Properties'), + Runtime.Ref('Properties'), Runtime.Const(RBrace) ], values => ObjectMapping(...values)) @@ -463,16 +339,16 @@ const Elements = Runtime.Union([ // prettier-ignore const Tuple = Runtime.Tuple([ Runtime.Const(LBracket), - Runtime.Ref('Elements'), + Runtime.Ref('Elements'), Runtime.Const(RBracket) -], value => Types.Tuple(value[1])) +], value => t.Tuple(value[1])) // ------------------------------------------------------------------ // Parameters // ------------------------------------------------------------------ // prettier-ignore const Parameter = Runtime.Tuple([ - Runtime.Ident(), Runtime.Const(Colon), Runtime.Ref('Type') + Runtime.Ident(), Runtime.Const(Colon), Runtime.Ref('Type') ], value => value[2]) // prettier-ignore const Parameters = Runtime.Union([ @@ -493,28 +369,28 @@ const Parameters = Runtime.Union([ const Constructor = Runtime.Tuple([ Runtime.Const('new'), Runtime.Const(LParen), - Runtime.Ref('Parameters'), + Runtime.Ref('Parameters'), Runtime.Const(RParen), Runtime.Const('=>'), - Runtime.Ref('Type') -], value => Types.Constructor(value[2], value[5])) + Runtime.Ref('Type') +], value => t.Constructor(value[2], value[5])) // ------------------------------------------------------------------ // Function // ------------------------------------------------------------------ // prettier-ignore const Function = Runtime.Tuple([ Runtime.Const(LParen), - Runtime.Ref('Parameters'), + Runtime.Ref('Parameters'), Runtime.Const(RParen), Runtime.Const('=>'), - Runtime.Ref('Type') -], value => Types.Function(value[1], value[4])) + Runtime.Ref('Type') +], value => t.Function(value[1], value[4])) // ------------------------------------------------------------------ // Mapped (requires deferred types) // ------------------------------------------------------------------ // prettier-ignore const MappedMapping = (values: unknown[]) => { - return Types.Literal('Mapped types not supported') + return t.Literal('Mapped types not supported') } // prettier-ignore const Mapped = Runtime.Tuple([ @@ -522,10 +398,10 @@ const Mapped = Runtime.Tuple([ Runtime.Const(LBracket), Runtime.Ident(), Runtime.Const('in'), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RBracket), Runtime.Const(Colon), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RBrace) ], MappedMapping) // ------------------------------------------------------------------ @@ -535,9 +411,9 @@ const Mapped = Runtime.Tuple([ const AsyncIterator = Runtime.Tuple([ Runtime.Const('AsyncIterator'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.AsyncIterator(value[2])) +], value => t.AsyncIterator(value[2])) // ------------------------------------------------------------------ // Iterator // ------------------------------------------------------------------ @@ -545,9 +421,9 @@ const AsyncIterator = Runtime.Tuple([ const Iterator = Runtime.Tuple([ Runtime.Const('Iterator'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Iterator(value[2])) +], value => t.Iterator(value[2])) // ------------------------------------------------------------------ // ConstructorParameters // ------------------------------------------------------------------ @@ -555,9 +431,9 @@ const Iterator = Runtime.Tuple([ const ConstructorParameters = Runtime.Tuple([ Runtime.Const('ConstructorParameters'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.ConstructorParameters(value[2])) +], value => t.ConstructorParameters(value[2])) // ------------------------------------------------------------------ // Parameters // ------------------------------------------------------------------ @@ -565,9 +441,9 @@ const ConstructorParameters = Runtime.Tuple([ const FunctionParameters = Runtime.Tuple([ Runtime.Const('Parameters'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Parameters(value[2])) +], value => t.Parameters(value[2])) // ------------------------------------------------------------------ // InstanceType // ------------------------------------------------------------------ @@ -575,9 +451,9 @@ const FunctionParameters = Runtime.Tuple([ const InstanceType = Runtime.Tuple([ Runtime.Const('InstanceType'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.InstanceType(value[2])) +], value => t.InstanceType(value[2])) // ------------------------------------------------------------------ // ReturnType // ------------------------------------------------------------------ @@ -585,9 +461,9 @@ const InstanceType = Runtime.Tuple([ const ReturnType = Runtime.Tuple([ Runtime.Const('ReturnType'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.ReturnType(value[2])) +], value => t.ReturnType(value[2])) // ------------------------------------------------------------------ // Awaited // ------------------------------------------------------------------ @@ -595,9 +471,9 @@ const ReturnType = Runtime.Tuple([ const Awaited = Runtime.Tuple([ Runtime.Const('Awaited'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Awaited(value[2])) +], value => t.Awaited(value[2])) // ------------------------------------------------------------------ // Array // ------------------------------------------------------------------ @@ -605,9 +481,9 @@ const Awaited = Runtime.Tuple([ const Array = Runtime.Tuple([ Runtime.Const('Array'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Array(value[2])) +], value => t.Array(value[2])) // ------------------------------------------------------------------ // Record // ------------------------------------------------------------------ @@ -615,11 +491,11 @@ const Array = Runtime.Tuple([ const Record = Runtime.Tuple([ Runtime.Const('Record'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(Comma), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Record(value[2], value[4])) +], value => t.Record(value[2], value[4])) // ------------------------------------------------------------------ // Promise // ------------------------------------------------------------------ @@ -627,9 +503,9 @@ const Record = Runtime.Tuple([ const Promise = Runtime.Tuple([ Runtime.Const('Promise'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Promise(value[2])) +], value => t.Promise(value[2])) // ------------------------------------------------------------------ // Partial // ------------------------------------------------------------------ @@ -637,9 +513,9 @@ const Promise = Runtime.Tuple([ const Partial = Runtime.Tuple([ Runtime.Const('Partial'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Partial(value[2])) +], value => t.Partial(value[2])) // ------------------------------------------------------------------ // Required // ------------------------------------------------------------------ @@ -647,9 +523,9 @@ const Partial = Runtime.Tuple([ const Required = Runtime.Tuple([ Runtime.Const('Required'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Required(value[2])) +], value => t.Required(value[2])) // ------------------------------------------------------------------ // Pick // ------------------------------------------------------------------ @@ -657,11 +533,11 @@ const Required = Runtime.Tuple([ const Pick = Runtime.Tuple([ Runtime.Const('Pick'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(Comma), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Pick(value[2], value[4])) +], value => t.Pick(value[2], value[4])) // ------------------------------------------------------------------ // Omit // ------------------------------------------------------------------ @@ -669,11 +545,11 @@ const Pick = Runtime.Tuple([ const Omit = Runtime.Tuple([ Runtime.Const('Omit'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(Comma), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Omit(value[2], value[4])) +], value => t.Omit(value[2], value[4])) // ------------------------------------------------------------------ // Exclude // ------------------------------------------------------------------ @@ -681,11 +557,11 @@ const Omit = Runtime.Tuple([ const Exclude = Runtime.Tuple([ Runtime.Const('Exclude'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(Comma), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Exclude(value[2], value[4])) +], value => t.Exclude(value[2], value[4])) // ------------------------------------------------------------------ // Extract // ------------------------------------------------------------------ @@ -693,11 +569,11 @@ const Exclude = Runtime.Tuple([ const Extract = Runtime.Tuple([ Runtime.Const('Extract'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(Comma), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Extract(value[2], value[4])) +], value => t.Extract(value[2], value[4])) // ------------------------------------------------------------------ // Uppercase // ------------------------------------------------------------------ @@ -705,9 +581,9 @@ const Extract = Runtime.Tuple([ const Uppercase = Runtime.Tuple([ Runtime.Const('Uppercase'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Uppercase(value[2])) +], value => t.Uppercase(value[2])) // ------------------------------------------------------------------ // Lowercase // ------------------------------------------------------------------ @@ -715,9 +591,9 @@ const Uppercase = Runtime.Tuple([ const Lowercase = Runtime.Tuple([ Runtime.Const('Lowercase'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Lowercase(value[2])) +], value => t.Lowercase(value[2])) // ------------------------------------------------------------------ // Capitalize // ------------------------------------------------------------------ @@ -725,9 +601,9 @@ const Lowercase = Runtime.Tuple([ const Capitalize = Runtime.Tuple([ Runtime.Const('Capitalize'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Capitalize(value[2])) +], value => t.Capitalize(value[2])) // ------------------------------------------------------------------ // Uncapitalize // ------------------------------------------------------------------ @@ -735,45 +611,22 @@ const Capitalize = Runtime.Tuple([ const Uncapitalize = Runtime.Tuple([ Runtime.Const('Uncapitalize'), Runtime.Const(LAngle), - Runtime.Ref('Type'), + Runtime.Ref('Type'), Runtime.Const(RAngle), -], value => Types.Uncapitalize(value[2])) +], value => t.Uncapitalize(value[2])) // ------------------------------------------------------------------ // Date // ------------------------------------------------------------------ -const Date = Runtime.Const('Date', Runtime.As(Types.Date())) +const Date = Runtime.Const('Date', Runtime.As(t.Date())) // ------------------------------------------------------------------ // Uint8Array // ------------------------------------------------------------------ -const Uint8Array = Runtime.Const('Uint8Array', Runtime.As(Types.Uint8Array())) - -// ------------------------------------------------------------------ -// Main -// ------------------------------------------------------------------ -// prettier-ignore -const Main = Runtime.Union([ - ModuleDeclaration, - TypeAliasDeclaration, - InterfaceDeclaration, - Type -]) +const Uint8Array = Runtime.Const('Uint8Array', Runtime.As(t.Uint8Array())) // ------------------------------------------------------------------ // Module // ------------------------------------------------------------------ // prettier-ignore export const Module = new Runtime.Module({ - // ---------------------------------------------------------------- - // Modules, Interfaces and Type Aliases - // ---------------------------------------------------------------- - ExportModifier, - HeritageList, - Heritage, - InterfaceDeclaration, - TypeAliasDeclaration, - ModuleType, - ModuleProperties, - ModuleDeclaration, - // ---------------------------------------------------------------- // Type Expressions // ---------------------------------------------------------------- @@ -826,9 +679,4 @@ export const Module = new Runtime.Module({ Date, Uint8Array, Reference, - - // ---------------------------------------------------------------- - // Main - // ---------------------------------------------------------------- - Main }) diff --git a/src/syntax/static.ts b/src/syntax/static.ts index 9d8bb0a3..4cd12556 100644 --- a/src/syntax/static.ts +++ b/src/syntax/static.ts @@ -26,8 +26,8 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ -import { Static } from './parsebox/index' -import * as Types from '../type/index' +import { Static } from '../parser/index' +import * as t from '../type/index' // ------------------------------------------------------------------ // Tokens @@ -139,147 +139,15 @@ type Delimit = // Deref // ------------------------------------------------------------------ // prettier-ignore -type Deref = ( - Ref extends keyof Context ? Context[Ref] : Types.TRef +type Deref = ( + Ref extends keyof Context ? Context[Ref] : t.TRef ) // ------------------------------------------------------------------ -// ExportModifier -// ------------------------------------------------------------------ -// prettier-ignore -interface ExportModifierMapping extends Static.IMapping { - output: this['input'] extends [string] ? true : false -} -// prettier-ignore -type ExportModifier = Static.Union<[ - Static.Tuple<[Static.Const<'export'>]>, - Static.Tuple<[]>, -], ExportModifierMapping> - -// ------------------------------------------------------------------ -// TypeAliasDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -interface TypeAliasDeclarationMapping extends Static.IMapping { - output: this['input'] extends [infer _Export extends boolean, 'type', infer Ident extends string, Equals, infer Type extends Types.TSchema] - ? { [_ in Ident]: Type } - : never -} -// prettier-ignore -type TypeAliasDeclaration = Static.Tuple<[ - ExportModifier, Static.Const<'type'>, Static.Ident, Static.Const, Type -], TypeAliasDeclarationMapping> - -// ------------------------------------------------------------------ -// HeritageList -// ------------------------------------------------------------------ -// prettier-ignore (note, heritage list should disallow trailing comma) -type HeritageListDelimiter = Static.Union<[Static.Tuple<[Static.Const, Static.Const]>, Static.Tuple<[Static.Const]>]> -// prettier-ignore -type HeritageListReduce = ( - Values extends [infer Ref extends string, ...infer Rest extends string[]] - ? HeritageListReduce]> - : Result -) -// prettier-ignore -interface HeritageListMapping extends Static.IMapping { - output: ( - this['context'] extends Types.TProperties ? - this['input'] extends string[] - ? HeritageListReduce - : [] - : [] - ) -} -// prettier-ignore -type HeritageList = Static.Union<[Delimit], HeritageListMapping> -// ------------------------------------------------------------------ -// Heritage -// ------------------------------------------------------------------ -// prettier-ignore -interface HeritageMapping extends Static.IMapping { - output: this['input'] extends ['extends', infer List extends Types.TSchema[]] ? List : [] -} -// prettier-ignore -type Heritage = Static.Union<[ - Static.Tuple<[Static.Const<'extends'>, HeritageList]>, - Static.Tuple<[]> -], HeritageMapping> -// ------------------------------------------------------------------ -// InterfaceDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -interface InterfaceDeclarationMapping extends Static.IMapping { - output: this['input'] extends [boolean, 'interface', infer Ident extends string, infer Heritage extends Types.TSchema[], LBrace, infer Properties extends Types.TProperties, RBrace] - ? { [_ in Ident]: Types.TIntersectEvaluated<[...Heritage, Types.TObject]> } - : never -} -// prettier-ignore -type InterfaceDeclaration = Static.Tuple<[ - ExportModifier, - Static.Const<'interface'>, - Static.Ident, - Heritage, - Static.Const, - Properties, - Static.Const, -], InterfaceDeclarationMapping> -// ------------------------------------------------------------------ -// ModuleType -// ------------------------------------------------------------------ -// prettier-ignore -type ModuleType = Static.Union<[ - InterfaceDeclaration, - TypeAliasDeclaration -]> -// ------------------------------------------------------------------ -// ModuleProperties -// ------------------------------------------------------------------ -// prettier-ignore -type ModulePropertiesDelimiter = Static.Union<[ - Static.Tuple<[Static.Const, Static.Const]>, - Static.Tuple<[Static.Const]>, - Static.Tuple<[Static.Const]>, -]> -// prettier-ignore -type ModulePropertiesReduce = ( - Value extends [infer ModuleType extends Types.TProperties, unknown[], ...infer Rest extends unknown[]] ? ModulePropertiesReduce : - Value extends [infer ModuleType extends Types.TProperties] ? ModulePropertiesReduce<[], Result & ModuleType> : - Types.Evaluate -) -// prettier-ignore -interface ModulePropertiesMapping extends Static.IMapping { - output: this['input'] extends unknown[] ? ModulePropertiesReduce : never -} -// prettier-ignore -type ModuleProperties = Static.Union<[ - Static.Tuple<[ModuleType, ModulePropertiesDelimiter, ModuleProperties]>, - Static.Tuple<[ModuleType]>, - Static.Tuple<[]>, -], ModulePropertiesMapping> -// ------------------------------------------------------------------ -// ModuleDeclaration -// ------------------------------------------------------------------ -// prettier-ignore -type ModuleIdentifier = Static.Union<[ - Static.Tuple<[Static.Ident]>, - Static.Tuple<[]> -]> -// prettier-ignore -interface ModuleDeclarationMapping extends Static.IMapping { - output: this['input'] extends [boolean, 'module', infer _Ident extends string[], LBrace, infer Properties extends Types.TProperties, RBrace] - ? Types.TModule - : never -} -// prettier-ignore -type ModuleDeclaration = Static.Tuple<[ - ExportModifier, Static.Const<'module'>, ModuleIdentifier, Static.Const, ModuleProperties, Static.Const -], ModuleDeclarationMapping> -// ------------------------------------------------------------------ // Reference // ------------------------------------------------------------------ // prettier-ignore interface ReferenceMapping extends Static.IMapping { - output: this['context'] extends Types.TProperties + output: this['context'] extends t.TProperties ? this['input'] extends string ? Deref : never @@ -291,15 +159,15 @@ type Reference = Static.Ident // ------------------------------------------------------------------ // prettier-ignore interface LiteralBooleanMapping extends Static.IMapping { - output: this['input'] extends `${infer S extends boolean}` ? Types.TLiteral : never + output: this['input'] extends `${infer S extends boolean}` ? t.TLiteral : never } // prettier-ignore interface LiteralNumberMapping extends Static.IMapping { - output: this['input'] extends `${infer S extends number}` ? Types.TLiteral : never + output: this['input'] extends `${infer S extends number}` ? t.TLiteral : never } // prettier-ignore interface LiteralStringMapping extends Static.IMapping { - output: this['input'] extends `${infer S extends string}` ? Types.TLiteral : never + output: this['input'] extends `${infer S extends string}` ? t.TLiteral : never } // prettier-ignore type Literal = Static.Union<[ @@ -312,18 +180,18 @@ type Literal = Static.Union<[ // ------------------------------------------------------------------ // prettier-ignore type Keyword = Static.Union<[ - Static.Const<'any', Static.As>, - Static.Const<'bigint', Static.As>, - Static.Const<'boolean', Static.As>, - Static.Const<'integer', Static.As>, - Static.Const<'never', Static.As>, - Static.Const<'null', Static.As>, - Static.Const<'number', Static.As>, - Static.Const<'string', Static.As>, - Static.Const<'symbol', Static.As>, - Static.Const<'undefined', Static.As>, - Static.Const<'unknown', Static.As>, - Static.Const<'void', Static.As>, + Static.Const<'any', Static.As>, + Static.Const<'bigint', Static.As>, + Static.Const<'boolean', Static.As>, + Static.Const<'integer', Static.As>, + Static.Const<'never', Static.As>, + Static.Const<'null', Static.As>, + Static.Const<'number', Static.As>, + Static.Const<'string', Static.As>, + Static.Const<'symbol', Static.As>, + Static.Const<'undefined', Static.As>, + Static.Const<'unknown', Static.As>, + Static.Const<'void', Static.As>, ]> // ------------------------------------------------------------------ // KeyOf @@ -343,7 +211,7 @@ type KeyOf = Static.Union<[ // prettier-ignore interface IndexArrayMapping extends Static.IMapping { output: ( - this['input'] extends [LBracket, infer Type extends Types.TSchema, RBracket, infer Rest extends unknown[]] ? [[Type], ...Rest] : + this['input'] extends [LBracket, infer Type extends t.TSchema, RBracket, infer Rest extends unknown[]] ? [[Type], ...Rest] : this['input'] extends [LBracket, RBracket, infer Rest extends unknown[]] ? [[], ...Rest] : [] ) @@ -360,7 +228,7 @@ type IndexArray = Static.Union<[ // ------------------------------------------------------------------ // prettier-ignore interface ExtendsMapping extends Static.IMapping { - output: this['input'] extends ['extends', infer Type extends Types.TSchema, Question, infer True extends Types.TSchema, Colon, infer False extends Types.TSchema] + output: this['input'] extends ['extends', infer Type extends t.TSchema, Question, infer True extends t.TSchema, Colon, infer False extends t.TSchema] ? [Type, True, False] : [] } @@ -375,8 +243,8 @@ type Extends = Static.Union<[ // prettier-ignore interface BaseMapping extends Static.IMapping { output: ( - this['input'] extends [LParen, infer Type extends Types.TSchema, RParen] ? Type : - this['input'] extends [infer Type extends Types.TSchema] ? Type : + this['input'] extends [LParen, infer Type extends t.TSchema, RParen] ? Type : + this['input'] extends [infer Type extends t.TSchema] ? Type : never ) } @@ -424,24 +292,24 @@ type Base = Static.Union<[ // Factor // ------------------------------------------------------------------ // prettier-ignore -type FactorExtends = ( - Extends extends [infer Right extends Types.TSchema, infer True extends Types.TSchema, infer False extends Types.TSchema] - ? Types.TExtends +type FactorExtends = ( + Extends extends [infer Right extends t.TSchema, infer True extends t.TSchema, infer False extends t.TSchema] + ? t.TExtends : Type ) // prettier-ignore -type FactorIndexArray = ( - IndexArray extends [...infer Left extends unknown[], infer Right extends Types.TSchema[]] ? ( - Right extends [infer Indexer extends Types.TSchema] ? Types.TIndex, Types.TIndexPropertyKeys> : - Right extends [] ? Types.TArray> : - Types.TNever +type FactorIndexArray = ( + IndexArray extends [...infer Left extends unknown[], infer Right extends t.TSchema[]] ? ( + Right extends [infer Indexer extends t.TSchema] ? t.TIndex, t.TIndexPropertyKeys> : + Right extends [] ? t.TArray> : + t.TNever ) : Type ) // prettier-ignore interface FactorMapping extends Static.IMapping { - output: this['input'] extends [infer KeyOf extends boolean, infer Type extends Types.TSchema, infer IndexArray extends unknown[], infer Extends extends unknown[]] + output: this['input'] extends [infer KeyOf extends boolean, infer Type extends t.TSchema, infer IndexArray extends unknown[], infer Extends extends unknown[]] ? KeyOf extends true - ? FactorExtends>, Extends> + ? FactorExtends>, Extends> : FactorExtends, Extends> : never } @@ -453,18 +321,18 @@ type Factor = Static.Tuple<[ // Expr // ------------------------------------------------------------------ // prettier-ignore -type ExprBinaryReduce = ( - Rest extends [infer Operator extends unknown, infer Right extends Types.TSchema, infer Next extends unknown[]] ? ( - ExprBinaryReduce extends infer Schema extends Types.TSchema ? ( +type ExprBinaryReduce = ( + Rest extends [infer Operator extends unknown, infer Right extends t.TSchema, infer Next extends unknown[]] ? ( + ExprBinaryReduce extends infer Schema extends t.TSchema ? ( Operator extends '&' ? ( - Schema extends Types.TIntersect - ? Types.TIntersect<[Left, ...Types]> - : Types.TIntersect<[Left, Schema]> + Schema extends t.TIntersect + ? t.TIntersect<[Left, ...Types]> + : t.TIntersect<[Left, Schema]> ) : Operator extends '|' ? ( - Schema extends Types.TUnion - ? Types.TUnion<[Left, ...Types]> - : Types.TUnion<[Left, Schema]> + Schema extends t.TUnion + ? t.TUnion<[Left, ...Types]> + : t.TUnion<[Left, Schema]> ) : never ) : never ) : Left @@ -472,7 +340,7 @@ type ExprBinaryReduce = ( // prettier-ignore interface ExprBinaryMapping extends Static.IMapping { output: ( - this['input'] extends [infer Left extends Types.TSchema, infer Rest extends unknown[]] + this['input'] extends [infer Left extends t.TSchema, infer Rest extends unknown[]] ? ExprBinaryReduce : [] ) @@ -498,7 +366,7 @@ type Expr = Static.Tuple<[ // ------------------------------------------------------------------ // Type // ------------------------------------------------------------------ -type Type = Expr +export type Type = Expr // ------------------------------------------------------------------ // Properties // ------------------------------------------------------------------ @@ -520,12 +388,12 @@ interface OptionalMapping extends Static.IMapping { type Optional = Static.Union<[Static.Tuple<[Static.Const]>, Static.Tuple<[]>], OptionalMapping> // prettier-ignore interface PropertyMapping extends Static.IMapping { - output: this['input'] extends [infer IsReadonly extends boolean, infer Key extends string, infer IsOptional extends boolean, string, infer Type extends Types.TSchema] + output: this['input'] extends [infer IsReadonly extends boolean, infer Key extends string, infer IsOptional extends boolean, string, infer Type extends t.TSchema] ? { [_ in Key]: ( - [IsReadonly, IsOptional] extends [true, true] ? Types.TReadonlyOptional : - [IsReadonly, IsOptional] extends [true, false] ? Types.TReadonly : - [IsReadonly, IsOptional] extends [false, true] ? Types.TOptional : + [IsReadonly, IsOptional] extends [true, true] ? t.TReadonlyOptional : + [IsReadonly, IsOptional] extends [true, false] ? t.TReadonly : + [IsReadonly, IsOptional] extends [false, true] ? t.TOptional : Type ) } : never @@ -540,14 +408,14 @@ type PropertyDelimiter = Static.Union<[ Static.Tuple<[Static.Const]>, ]> // prettier-ignore -type PropertiesReduce = ( - PropertiesArray extends [infer Left extends Types.TProperties, ...infer Right extends Types.TProperties[]] - ? PropertiesReduce> +type PropertiesReduce = ( + PropertiesArray extends [infer Left extends t.TProperties, ...infer Right extends t.TProperties[]] + ? PropertiesReduce> : Result ) // prettier-ignore interface PropertiesMapping extends Static.IMapping { - output: this['input'] extends Types.TProperties[] ? PropertiesReduce : never + output: this['input'] extends t.TProperties[] ? PropertiesReduce : never } type Properties = Static.Union<[Delimit], PropertiesMapping> // ------------------------------------------------------------------ @@ -555,8 +423,8 @@ type Properties = Static.Union<[Delimit], Propertie // ------------------------------------------------------------------ // prettier-ignore interface ObjectMapping extends Static.IMapping { - output: this['input'] extends [unknown, infer Properties extends Types.TProperties, unknown] - ? Types.TObject + output: this['input'] extends [unknown, infer Properties extends t.TProperties, unknown] + ? t.TObject : never } // prettier-ignore @@ -569,7 +437,7 @@ type Object = Static.Tuple<[ type Elements = Delimit> // prettier-ignore interface TupleMapping extends Static.IMapping { - output: this['input'] extends [unknown, infer Elements extends Types.TSchema[], unknown] ? Types.TTuple : never + output: this['input'] extends [unknown, infer Elements extends t.TSchema[], unknown] ? t.TTuple : never } // prettier-ignore type Tuple = Static.Tuple<[ @@ -579,7 +447,7 @@ type Tuple = Static.Tuple<[ // Parameters // ------------------------------------------------------------------ interface ParameterMapping extends Static.IMapping { - output: this['input'] extends [string, Colon, infer Type extends Types.TSchema] ? Type : never + output: this['input'] extends [string, Colon, infer Type extends t.TSchema] ? Type : never } // prettier-ignore type Parameter = Static.Tuple<[ @@ -592,8 +460,8 @@ type Parameters = Delimit> // ------------------------------------------------------------------ // prettier-ignore interface FunctionMapping extends Static.IMapping { - output: this['input'] extends [LParen, infer Parameters extends Types.TSchema[], RParen, '=>', infer ReturnType extends Types.TSchema] - ? Types.TFunction + output: this['input'] extends [LParen, infer Parameters extends t.TSchema[], RParen, '=>', infer ReturnType extends t.TSchema] + ? t.TFunction : never } // prettier-ignore @@ -605,8 +473,8 @@ type Function = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ConstructorMapping extends Static.IMapping { - output: this['input'] extends ['new', LParen, infer Parameters extends Types.TSchema[], RParen, '=>', infer InstanceType extends Types.TSchema] - ? Types.TConstructor + output: this['input'] extends ['new', LParen, infer Parameters extends t.TSchema[], RParen, '=>', infer InstanceType extends t.TSchema] + ? t.TConstructor : never } // prettier-ignore @@ -618,8 +486,8 @@ type Constructor = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface MappedMapping extends Static.IMapping { - output: this['input'] extends [LBrace, LBracket, infer _Key extends string, 'in', infer _Right extends Types.TSchema, RBracket, Colon, infer Type extends Types.TSchema, RBrace] - ? Types.TLiteral<'Mapped types not supported'> + output: this['input'] extends [LBrace, LBracket, infer _Key extends string, 'in', infer _Right extends t.TSchema, RBracket, Colon, infer Type extends t.TSchema, RBrace] + ? t.TLiteral<'Mapped types not supported'> : this['input'] } // prettier-ignore @@ -631,8 +499,8 @@ type Mapped = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ArrayMapping extends Static.IMapping { - output: this['input'] extends ['Array', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TArray + output: this['input'] extends ['Array', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TArray : never } // prettier-ignore @@ -644,8 +512,8 @@ type Array = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface AsyncIteratorMapping extends Static.IMapping { - output: this['input'] extends ['AsyncIterator', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TAsyncIterator + output: this['input'] extends ['AsyncIterator', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TAsyncIterator : never } // prettier-ignore @@ -657,8 +525,8 @@ type AsyncIterator = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface IteratorMapping extends Static.IMapping { - output: this['input'] extends ['Iterator', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TIterator + output: this['input'] extends ['Iterator', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TIterator : never } // prettier-ignore @@ -671,8 +539,8 @@ type Iterator = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ConstructorParametersMapping extends Static.IMapping { - output: this['input'] extends ['ConstructorParameters', LAngle, infer Type extends Types.TConstructor, RAngle] - ? Types.TConstructorParameters + output: this['input'] extends ['ConstructorParameters', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TConstructorParameters : never } // prettier-ignore @@ -684,8 +552,8 @@ type ConstructorParameters = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface FunctionParametersMapping extends Static.IMapping { - output: this['input'] extends ['Parameters', LAngle, infer Type extends Types.TFunction, RAngle] - ? Types.TParameters + output: this['input'] extends ['Parameters', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TParameters : never } // prettier-ignore @@ -697,8 +565,8 @@ type FunctionParameters = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface InstanceTypeMapping extends Static.IMapping { - output: this['input'] extends ['InstanceType', LAngle, infer Type extends Types.TConstructor, RAngle] - ? Types.TInstanceType + output: this['input'] extends ['InstanceType', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TInstanceType : never } // prettier-ignore @@ -710,8 +578,8 @@ type InstanceType = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ReturnTypeMapping extends Static.IMapping { - output: this['input'] extends ['ReturnType', LAngle, infer Type extends Types.TFunction, RAngle] - ? Types.TReturnType + output: this['input'] extends ['ReturnType', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TReturnType : never } // prettier-ignore @@ -723,8 +591,8 @@ type ReturnType = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface AwaitedMapping extends Static.IMapping { - output: this['input'] extends ['Awaited', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TAwaited + output: this['input'] extends ['Awaited', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TAwaited : never } // prettier-ignore @@ -736,8 +604,8 @@ type Awaited = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface PromiseMapping extends Static.IMapping { - output: this['input'] extends ['Promise', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TPromise + output: this['input'] extends ['Promise', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TPromise : never } // prettier-ignore @@ -749,8 +617,8 @@ type Promise = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface RecordMapping extends Static.IMapping { - output: this['input'] extends ['Record', LAngle, infer Key extends Types.TSchema, Comma, infer Type extends Types.TSchema, RAngle] - ? Types.TRecord + output: this['input'] extends ['Record', LAngle, infer Key extends t.TSchema, Comma, infer Type extends t.TSchema, RAngle] + ? t.TRecord : never } // prettier-ignore @@ -762,8 +630,8 @@ type Record = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface PartialMapping extends Static.IMapping { - output: this['input'] extends ['Partial', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TPartial + output: this['input'] extends ['Partial', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TPartial : never } // prettier-ignore @@ -775,8 +643,8 @@ type Partial = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface RequiredMapping extends Static.IMapping { - output: this['input'] extends ['Required', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TRequired + output: this['input'] extends ['Required', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TRequired : never } // prettier-ignore @@ -788,8 +656,8 @@ type Required = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface PickMapping extends Static.IMapping { - output: this['input'] extends ['Pick', LAngle, infer Type extends Types.TSchema, Comma, infer Key extends Types.TSchema, RAngle] - ? Types.TPick + output: this['input'] extends ['Pick', LAngle, infer Type extends t.TSchema, Comma, infer Key extends t.TSchema, RAngle] + ? t.TPick : never } // prettier-ignore @@ -801,8 +669,8 @@ type Pick = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface OmitMapping extends Static.IMapping { - output: this['input'] extends ['Omit', LAngle, infer Type extends Types.TSchema, Comma, infer Key extends Types.TSchema, RAngle] - ? Types.TOmit + output: this['input'] extends ['Omit', LAngle, infer Type extends t.TSchema, Comma, infer Key extends t.TSchema, RAngle] + ? t.TOmit : never } // prettier-ignore @@ -814,8 +682,8 @@ type Omit = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ExcludeMapping extends Static.IMapping { - output: this['input'] extends ['Exclude', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle] - ? Types.TExclude + output: this['input'] extends ['Exclude', LAngle, infer Type extends t.TSchema, Comma, infer PropertyKey extends t.TSchema, RAngle] + ? t.TExclude : never } // prettier-ignore @@ -827,8 +695,8 @@ type Exclude = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface ExtractMapping extends Static.IMapping { - output: this['input'] extends ['Extract', LAngle, infer Type extends Types.TSchema, Comma, infer PropertyKey extends Types.TSchema, RAngle] - ? Types.TExtract + output: this['input'] extends ['Extract', LAngle, infer Type extends t.TSchema, Comma, infer PropertyKey extends t.TSchema, RAngle] + ? t.TExtract : never } // prettier-ignore @@ -840,8 +708,8 @@ type Extract = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface UppercaseMapping extends Static.IMapping { - output: this['input'] extends ['Uppercase', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TUppercase + output: this['input'] extends ['Uppercase', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TUppercase : never } // prettier-ignore @@ -853,8 +721,8 @@ type Uppercase = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface LowercaseMapping extends Static.IMapping { - output: this['input'] extends ['Lowercase', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TLowercase + output: this['input'] extends ['Lowercase', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TLowercase : never } // prettier-ignore @@ -866,8 +734,8 @@ type Lowercase = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface CapitalizeMapping extends Static.IMapping { - output: this['input'] extends ['Capitalize', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TCapitalize + output: this['input'] extends ['Capitalize', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TCapitalize : never } // prettier-ignore @@ -879,8 +747,8 @@ type Capitalize = Static.Tuple<[ // ------------------------------------------------------------------ // prettier-ignore interface UncapitalizeMapping extends Static.IMapping { - output: this['input'] extends ['Uncapitalize', LAngle, infer Type extends Types.TSchema, RAngle] - ? Types.TUncapitalize + output: this['input'] extends ['Uncapitalize', LAngle, infer Type extends t.TSchema, RAngle] + ? t.TUncapitalize : never } // prettier-ignore @@ -890,19 +758,8 @@ type Uncapitalize = Static.Tuple<[ // ------------------------------------------------------------------ // Date // ------------------------------------------------------------------ -type Date = Static.Const<'Date', Static.As> +type Date = Static.Const<'Date', Static.As> // ------------------------------------------------------------------ // Uint8Array // ------------------------------------------------------------------ -type Uint8Array = Static.Const<'Uint8Array', Static.As> - -// ------------------------------------------------------------------ -// Main -// ------------------------------------------------------------------ -// prettier-ignore -export type Main = Static.Union<[ - ModuleDeclaration, - TypeAliasDeclaration, - InterfaceDeclaration, - Type -]> +type Uint8Array = Static.Const<'Uint8Array', Static.As> diff --git a/src/syntax/syntax.ts b/src/syntax/syntax.ts new file mode 100644 index 00000000..d0f7114c --- /dev/null +++ b/src/syntax/syntax.ts @@ -0,0 +1,101 @@ +/*-------------------------------------------------------------------------- + +@sinclair/typebox/syntax + +The MIT License (MIT) + +Copyright (c) 2017-2025 Haydn Paterson (sinclair) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +---------------------------------------------------------------------------*/ + +import * as Types from '../type/index' +import { Static } from '../parser/index' +import { Module } from './runtime' +import { Type } from './static' + +/** Infers a TSchema from Syntax. */ +// prettier-ignore +export type TSyntax, Code extends string> = ( + Static.Parse extends [infer Type extends Types.TSchema, string] + ? Type + : Types.TNever +) +/** Parses a TSchema type from Syntax. */ +export function Syntax, Code extends string>(context: Context, code: Code, options?: Types.SchemaOptions): TSyntax +/** Parses a TSchema type from Syntax. */ +export function Syntax(code: Code, options?: Types.SchemaOptions): TSyntax<{}, Code> +/** Parses a TSchema type from Syntax. */ +export function Syntax(...args: any[]): never { + return NoInfer.apply(null, args as never) as never +} +/** Parses a TSchema from TypeScript Syntax */ +export function NoInfer, Code extends string>(context: Context, code: Code, options?: Types.SchemaOptions): Types.TSchema | undefined +/** Parses a TSchema from TypeScript Syntax */ +export function NoInfer(code: Code, options?: Types.SchemaOptions): Types.TSchema | undefined +/** Parses a TSchema from TypeScript Syntax */ +// prettier-ignore +export function NoInfer(...args: any[]): Types.TSchema | undefined { + const withContext = typeof args[0] === 'string' ? false : true + const [context, code, options] = withContext ? [args[0], args[1], args[2] || {}] : [{}, args[0], args[1] || {}] + const type = Module.Parse('Type', code, context)[0] + return Types.KindGuard.IsSchema(type) + ? Types.CloneType(type, options) + : Types.Never(options) +} + +// ------------------------------------------------------------------ +// Deprecated +// ------------------------------------------------------------------ +/** + * Parses a TSchema type from Syntax. + * @deprecated Use Syntax() function + */ +export function Parse, Code extends string>(context: Context, code: Code, options?: Types.SchemaOptions): TSyntax +/** + * Parses a TSchema type from Syntax. + * @deprecated Use Syntax() function + */ +export function Parse(code: Code, options?: Types.SchemaOptions): TSyntax<{}, Code> +/** + * Parses a TSchema type from Syntax. + * @deprecated Use Syntax() function + */ +export function Parse(...args: any[]): never { + return NoInfer.apply(null, args as never) as never +} + +/** + * Parses a TSchema from TypeScript Syntax + * @deprecated Use NoInfer() function + */ +export function ParseOnly, Code extends string>(context: Context, code: Code, options?: Types.SchemaOptions): Types.TSchema | undefined +/** + * Parses a TSchema from TypeScript Syntax + * @deprecated Use NoInfer() function + */ +export function ParseOnly(code: Code, options?: Types.SchemaOptions): Types.TSchema | undefined +/** + * Parses a TSchema from TypeScript Syntax + * @deprecated Use NoInfer() function + */ +export function ParseOnly(...args: any[]): Types.TSchema | undefined { + return NoInfer.apply(null, args as never) as never +} diff --git a/src/tsconfig.json b/src/tsconfig.json index 89a62a89..e65c0640 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -1,4 +1,4 @@ { "extends": "../tsconfig.json", - "files": ["compiler/index.ts", "errors/index.ts", "syntax/index.ts", "system/index.ts", "type/index.ts", "value/index.ts", "index.ts"] + "files": ["compiler/index.ts", "errors/index.ts", "parser/index.ts", "syntax/index.ts", "system/index.ts", "type/index.ts", "value/index.ts", "index.ts"] } diff --git a/src/type/constructor-parameters/constructor-parameters.ts b/src/type/constructor-parameters/constructor-parameters.ts index b15718f1..3947c853 100644 --- a/src/type/constructor-parameters/constructor-parameters.ts +++ b/src/type/constructor-parameters/constructor-parameters.ts @@ -27,19 +27,21 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ import type { TSchema, SchemaOptions } from '../schema/index' -import type { Ensure } from '../helpers/index' import type { TConstructor } from '../constructor/index' import { Tuple, type TTuple } from '../tuple/index' +import { Never, type TNever } from '../never/index' +import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // ConstructorParameters // ------------------------------------------------------------------ // prettier-ignore -export type TConstructorParameters> = ( - Ensure> +export type TConstructorParameters = ( + Type extends TConstructor + ? TTuple + : TNever ) - /** `[JavaScript]` Extracts the ConstructorParameters from the given Constructor type */ -export function ConstructorParameters>(schema: T, options?: SchemaOptions): TConstructorParameters { - return Tuple(schema.parameters, options) +export function ConstructorParameters(schema: Type, options?: SchemaOptions): TConstructorParameters { + return (KindGuard.IsConstructor(schema) ? Tuple(schema.parameters, options) : Never(options)) as never } diff --git a/src/type/instance-type/instance-type.ts b/src/type/instance-type/instance-type.ts index ece1382c..7bba6663 100644 --- a/src/type/instance-type/instance-type.ts +++ b/src/type/instance-type/instance-type.ts @@ -27,12 +27,19 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' -import type { TSchema, SchemaOptions } from '../schema/index' -import type { TConstructor } from '../constructor/index' - -export type TInstanceType> = T['returns'] +import { type TSchema, SchemaOptions } from '../schema/index' +import { type TConstructor } from '../constructor/index' +import { type TNever, Never } from '../never/index' +import * as KindGuard from '../guard/kind' + +// prettier-ignore +export type TInstanceType + ? InstanceType + : TNever +> = Result /** `[JavaScript]` Extracts the InstanceType from the given Constructor type */ -export function InstanceType>(schema: T, options?: SchemaOptions): TInstanceType { - return CreateType(schema.returns, options) +export function InstanceType(schema: Type, options?: SchemaOptions): TInstanceType { + return (KindGuard.IsConstructor(schema) ? CreateType(schema.returns, options) : Never(options)) as never } diff --git a/src/type/parameters/parameters.ts b/src/type/parameters/parameters.ts index d36ed9a1..02ec7950 100644 --- a/src/type/parameters/parameters.ts +++ b/src/type/parameters/parameters.ts @@ -28,15 +28,20 @@ THE SOFTWARE. import type { TSchema, SchemaOptions } from '../schema/index' import type { TFunction } from '../function/index' -import type { Ensure } from '../helpers/index' import { Tuple, type TTuple } from '../tuple/index' +import { Never, type TNever } from '../never/index' +import * as KindGuard from '../guard/kind' // ------------------------------------------------------------------ // Parameters // ------------------------------------------------------------------ -export type TParameters = Ensure> - +// prettier-ignore +export type TParameters = ( + Type extends TFunction + ? TTuple + : TNever +) /** `[JavaScript]` Extracts the Parameters from the given Function type */ -export function Parameters>(schema: T, options?: SchemaOptions): TParameters { - return Tuple(schema.parameters, options) +export function Parameters(schema: Type, options?: SchemaOptions): TParameters { + return (KindGuard.IsFunction(schema) ? Tuple(schema.parameters, options) : Never()) as never } diff --git a/src/type/return-type/return-type.ts b/src/type/return-type/return-type.ts index 17dd4475..1b44968d 100644 --- a/src/type/return-type/return-type.ts +++ b/src/type/return-type/return-type.ts @@ -27,12 +27,19 @@ THE SOFTWARE. ---------------------------------------------------------------------------*/ import { CreateType } from '../create/type' -import type { SchemaOptions } from '../schema/index' -import type { TFunction } from '../function/index' - -export type TReturnType = T['returns'] +import { type TSchema, type SchemaOptions } from '../schema/index' +import { type TFunction } from '../function/index' +import { type TNever, Never } from '../never/index' +import * as KindGuard from '../guard/kind' + +// prettier-ignore +export type TReturnType + ? ReturnType + : TNever +> = Result /** `[JavaScript]` Extracts the ReturnType from the given Function type */ -export function ReturnType>(schema: T, options?: SchemaOptions): TReturnType { - return CreateType(schema.returns, options) as never +export function ReturnType(schema: Type, options?: SchemaOptions): TReturnType { + return (KindGuard.IsFunction(schema) ? CreateType(schema.returns, options) : Never(options)) as never } diff --git a/src/type/type/javascript.ts b/src/type/type/javascript.ts index a7d6573d..13705e5d 100644 --- a/src/type/type/javascript.ts +++ b/src/type/type/javascript.ts @@ -61,7 +61,7 @@ export class JavaScriptTypeBuilder extends JsonTypeBuilder { return BigInt(options) } /** `[JavaScript]` Extracts the ConstructorParameters from the given Constructor type */ - public ConstructorParameters(schema: Type, options?: SchemaOptions): TConstructorParameters { + public ConstructorParameters(schema: Type, options?: SchemaOptions): TConstructorParameters { return ConstructorParameters(schema, options) } /** `[JavaScript]` Creates a Constructor type */ @@ -77,7 +77,7 @@ export class JavaScriptTypeBuilder extends JsonTypeBuilder { return FunctionType(parameters, returnType, options) } /** `[JavaScript]` Extracts the InstanceType from the given Constructor type */ - public InstanceType(schema: Type, options?: SchemaOptions): TInstanceType { + public InstanceType(schema: Type, options?: SchemaOptions): TInstanceType { return InstanceType(schema, options) } /** `[JavaScript]` Creates an Iterator type */ @@ -85,7 +85,7 @@ export class JavaScriptTypeBuilder extends JsonTypeBuilder { return Iterator(items, options) } /** `[JavaScript]` Extracts the Parameters from the given Function type */ - public Parameters(schema: Type, options?: SchemaOptions): TParameters { + public Parameters(schema: Type, options?: SchemaOptions): TParameters { return Parameters(schema, options) } /** `[JavaScript]` Creates a Promise type */ @@ -101,7 +101,7 @@ export class JavaScriptTypeBuilder extends JsonTypeBuilder { return RegExp(unresolved as any, options) } /** `[JavaScript]` Extracts the ReturnType from the given Function type */ - public ReturnType(type: Type, options?: SchemaOptions): TReturnType { + public ReturnType(type: Type, options?: SchemaOptions): TReturnType { return ReturnType(type, options) } /** `[JavaScript]` Creates a Symbol type */ diff --git a/task/build/package/build.ts b/task/build/package/build.ts index 305ebbd1..a4b3c588 100644 --- a/task/build/package/build.ts +++ b/task/build/package/build.ts @@ -32,7 +32,7 @@ import { createPackageJson } from './create-package-json' /** Builds package.json and redirect directories */ export async function build(target: string) { console.log('building...package.json') - const submodules = ['compiler', 'errors', 'syntax', 'system', 'type', 'value'] + const submodules = ['compiler', 'errors', 'parser', 'syntax', 'system', 'type', 'value'] await createPackageJsonRedirect(target, submodules) await createPackageJson(target, submodules) } diff --git a/test/runtime/syntax/syntax.ts b/test/runtime/syntax/syntax.ts index ae705675..6f66c2ec 100644 --- a/test/runtime/syntax/syntax.ts +++ b/test/runtime/syntax/syntax.ts @@ -1,156 +1,69 @@ import { TypeGuard } from '@sinclair/typebox' -import { Type, TModule } from '@sinclair/typebox' -import { Parse } from '@sinclair/typebox/syntax' +import { Type } from '@sinclair/typebox' +import { Syntax } from '@sinclair/typebox/syntax' import { Assert } from '../assert/index' // prettier-ignore -describe('syntax/Parse', () => { - // ---------------------------------------------------------------- - // Type Alias - // ---------------------------------------------------------------- - it('Should parse Type Alias 1', () => { - const T = Parse('type A = 1') - Assert.IsTrue(TypeGuard.IsLiteral(T.A)) - Assert.IsTrue(T.A.const === 1) - }) - it('Should parse Type Alias 2', () => { - const T = Parse('export type A = 1') - Assert.IsTrue(TypeGuard.IsLiteral(T.A)) - Assert.IsTrue(T.A.const === 1) - }) - // ---------------------------------------------------------------- - // Interface - // ---------------------------------------------------------------- - it('Should parse Interface 1', () => { - const T = Parse('interface A { x: 1 }') - Assert.IsTrue(TypeGuard.IsObject(T.A)) - Assert.IsTrue(TypeGuard.IsLiteral(T.A.properties.x)) - Assert.IsTrue(T.A.properties.x.const === 1) - }) - it('Should parse Interface 2', () => { - const T = Parse('export interface A { x: 1 }') - Assert.IsTrue(TypeGuard.IsObject(T.A)) - Assert.IsTrue(TypeGuard.IsLiteral(T.A.properties.x)) - Assert.IsTrue(T.A.properties.x.const === 1) - }) - // ---------------------------------------------------------------- - // Module - // ---------------------------------------------------------------- - it('Should parse Module 1', () => { - const T = Parse('module {}') - Assert.IsTrue(T instanceof TModule) - }) - it('Should parse Module 2', () => { - const T = Parse('export module {}') - Assert.IsTrue(T instanceof TModule) - }) - it('Should parse Module 3', () => { - const T = Parse('module A {}') - Assert.IsTrue(T instanceof TModule) - }) - it('Should parse Module 4', () => { - const T = Parse('export module A {}') - Assert.IsTrue(T instanceof TModule) - }) - it('Should parse Module 5', () => { - const T = Parse(`export module A { - export type A = number - }`) - const A = T.Import('A') - Assert.IsTrue(T instanceof TModule) - Assert.IsTrue(TypeGuard.IsImport(A)) - const N = A.$defs[A.$ref] - Assert.IsTrue(TypeGuard.IsNumber(N)) - }) - it('Should parse Module 6', () => { - const T = Parse(`export module A { - export interface A { x: number } - }`) - const A = T.Import('A') - Assert.IsTrue(T instanceof TModule) - Assert.IsTrue(TypeGuard.IsImport(A)) - const N = A.$defs[A.$ref] - Assert.IsTrue(TypeGuard.IsObject(N)) - Assert.IsTrue(TypeGuard.IsNumber(N.properties.x)) - }) - it('Should parse Module 7', () => { - const T = Parse(`export module A { - export interface A { x: number } - export type B = number - }`) - // A - const A = T.Import('A') - Assert.IsTrue(T instanceof TModule) - Assert.IsTrue(TypeGuard.IsImport(A)) - const N1 = A.$defs[A.$ref] - Assert.IsTrue(TypeGuard.IsObject(N1)) - Assert.IsTrue(TypeGuard.IsNumber(N1.properties.x)) - // B - const B = T.Import('B') - Assert.IsTrue(T instanceof TModule) - Assert.IsTrue(TypeGuard.IsImport(B)) - const N2 = B.$defs[B.$ref] - Assert.IsTrue(TypeGuard.IsNumber(N2)) - }) +describe('syntax/Syntax', () => { // ---------------------------------------------------------------- // Type Expressions // ---------------------------------------------------------------- it('Should parse Any', () => { - const T = Parse(`any`) + const T = Syntax(`any`) Assert.IsTrue(TypeGuard.IsAny(T)) }) it('Should parse Array 1', () => { - const T = Parse(`number[]`) + const T = Syntax(`number[]`) Assert.IsTrue(TypeGuard.IsArray(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse Array 2', () => { - const T = Parse(`Array`) + const T = Syntax(`Array`) Assert.IsTrue(TypeGuard.IsArray(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse AsyncIterator', () => { - const T = Parse(`AsyncIterator`) + const T = Syntax(`AsyncIterator`) Assert.IsTrue(TypeGuard.IsAsyncIterator(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse Awaited', () => { - const T = Parse(`Awaited>`) + const T = Syntax(`Awaited>`) Assert.IsTrue(TypeGuard.IsNumber(T)) }) it('Should parse BigInt', () => { - const T = Parse(`bigint`) + const T = Syntax(`bigint`) Assert.IsTrue(TypeGuard.IsBigInt(T)) }) it('Should parse Boolean', () => { - const T = Parse(`boolean`) + const T = Syntax(`boolean`) Assert.IsTrue(TypeGuard.IsBoolean(T)) }) it('Should parse ConstructorParameters', () => { - const T = Parse(`ConstructorParameters boolean>`) + const T = Syntax(`ConstructorParameters boolean>`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsString(T.items![1])) }) it('Should parse Constructor', () => { - const T = Parse(`new (a: number, b: string) => boolean`) + const T = Syntax(`new (a: number, b: string) => boolean`) Assert.IsTrue(TypeGuard.IsConstructor(T)) Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0])) Assert.IsTrue(TypeGuard.IsString(T.parameters[1])) Assert.IsTrue(TypeGuard.IsBoolean(T.returns)) }) it('Should parse Date', () => { - const T = Parse(`Date`) + const T = Syntax(`Date`) Assert.IsTrue(TypeGuard.IsDate(T)) }) it('Should parse Exclude', () => { - const T = Parse(`Exclude<1 | 2 | 3, 1>`) + const T = Syntax(`Exclude<1 | 2 | 3, 1>`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 2) Assert.IsTrue(T.anyOf[1].const === 3) }) it('Should parse Extract', () => { - const T = Parse(`Extract<1 | 2 | 3, 1 | 2>`) + const T = Syntax(`Extract<1 | 2 | 3, 1 | 2>`) Assert.IsTrue(TypeGuard.IsUnion(T)) // @ts-ignore fix: incorrect union order (result of UnionToTuple, replace with Tuple destructuring) Assert.IsTrue(T.anyOf[0].const === 1) @@ -158,144 +71,144 @@ describe('syntax/Parse', () => { Assert.IsTrue(T.anyOf[1].const === 2) }) it('Should parse Function', () => { - const T = Parse(`(a: number, b: string) => boolean`) + const T = Syntax(`(a: number, b: string) => boolean`) Assert.IsTrue(TypeGuard.IsFunction(T)) Assert.IsTrue(TypeGuard.IsNumber(T.parameters[0])) Assert.IsTrue(TypeGuard.IsString(T.parameters[1])) Assert.IsTrue(TypeGuard.IsBoolean(T.returns)) }) it('Should parse Indexed 1', () => { - const T = Parse(`{ x: 1, y: 2, z: 3 }['x']`) + const T = Syntax(`{ x: 1, y: 2, z: 3 }['x']`) Assert.IsTrue(T.const === 1) }) it('Should parse Indexed 2', () => { - const T = Parse(`{ x: 1, y: 2, z: 3 }['x' | 'y' | 'z']`) + const T = Syntax(`{ x: 1, y: 2, z: 3 }['x' | 'y' | 'z']`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) Assert.IsTrue(T.anyOf[2].const === 3) }) it('Should parse Indexed 3', () => { - const T = Parse(`{ x: 1, y: 2, z: 3 }`) - const S = Parse({ T }, `T[keyof T]`) + const T = Syntax(`{ x: 1, y: 2, z: 3 }`) + const S = Syntax({ T }, `T[keyof T]`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 1) Assert.IsTrue(S.anyOf[1].const === 2) Assert.IsTrue(S.anyOf[2].const === 3) }) it('Should parse Indexed 4', () => { - const T = Parse(`['A', 'B', 'C']`) - const S = Parse({ T }, `T[number]`) + const T = Syntax(`['A', 'B', 'C']`) + const S = Syntax({ T }, `T[number]`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 'A') Assert.IsTrue(S.anyOf[1].const === 'B') Assert.IsTrue(S.anyOf[2].const === 'C') }) it('Should parse Integer', () => { - const T = Parse(`integer`) + const T = Syntax(`integer`) Assert.IsTrue(TypeGuard.IsInteger(T)) }) it('Should parse Intersect 1', () => { - const T = Parse(`1 & 2`) + const T = Syntax(`1 & 2`) Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(T.allOf[0].const === 1) Assert.IsTrue(T.allOf[1].const === 2) }) it('Should parse Intersect 2', () => { - const T = Parse(`1 & (2 & 3)`) // expect flatten + const T = Syntax(`1 & (2 & 3)`) // expect flatten Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(T.allOf[0].const === 1) Assert.IsTrue(T.allOf[1].const === 2) Assert.IsTrue(T.allOf[2].const === 3) }) it('Should parse Intersect 3', () => { - const T = Parse(`(1 | 2) & 3`) // operator precedence + const T = Syntax(`(1 | 2) & 3`) // operator precedence Assert.IsTrue(TypeGuard.IsIntersect(T)) Assert.IsTrue(TypeGuard.IsUnion(T.allOf[0])) Assert.IsTrue(T.allOf[1].const === 3) }) it('Should parse InstanceType 1', () => { - const T = Parse(`InstanceType { x: 1, y: 2 }>`) + const T = Syntax(`InstanceType { x: 1, y: 2 }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(T.properties.x.const === 1) Assert.IsTrue(T.properties.y.const === 2) }) it('Should parse InstanceType 2', () => { - const T = Parse(`InstanceType`) // generalization issue - Assert.IsTrue(T === undefined) + const T = Syntax(`InstanceType`) // generalization issue + Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse Iterator', () => { - const T = Parse(`Iterator`) + const T = Syntax(`Iterator`) Assert.IsTrue(TypeGuard.IsIterator(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items)) }) it('Should parse KeyOf 1', () => { - const T = Parse(`keyof { x: 1, y: 2 }`) + const T = Syntax(`keyof { x: 1, y: 2 }`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 'x') Assert.IsTrue(T.anyOf[1].const === 'y') }) it('Should parse KeyOf 2', () => { - const T = Parse(`keyof [0, 1]`) + const T = Syntax(`keyof [0, 1]`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === '0') Assert.IsTrue(T.anyOf[1].const === '1') }) it('Should parse KeyOf 3', () => { - const T = Parse(`{ x: 1, y: 2 }`) - const S = Parse({ T }, `keyof T`) + const T = Syntax(`{ x: 1, y: 2 }`) + const S = Syntax({ T }, `keyof T`) Assert.IsTrue(TypeGuard.IsUnion(S)) Assert.IsTrue(S.anyOf[0].const === 'x') Assert.IsTrue(S.anyOf[1].const === 'y') }) it('Should parse Literal Boolean 1', () => { - const T = Parse(`true`) + const T = Syntax(`true`) Assert.IsTrue(T.const === true) }) it('Should parse Literal Boolean 2', () => { - const T = Parse(`false`) + const T = Syntax(`false`) Assert.IsTrue(T.const === false) }) it('Should parse Literal Number', () => { - const T = Parse(`1`) + const T = Syntax(`1`) Assert.IsTrue(T.const === 1) }) it('Should parse Literal String', () => { - const T = Parse(`'1'`) + const T = Syntax(`'1'`) Assert.IsTrue(T.const === '1') }) it('Should parse Mapped (Pending)', () => { - const T = Parse(`{ [K in 1 | 2 | 3]: K }`) + const T = Syntax(`{ [K in 1 | 2 | 3]: K }`) Assert.IsTrue(T.const === 'Mapped types not supported') }) it('Should parse Never', () => { - const T = Parse(`never`) + const T = Syntax(`never`) Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse Null', () => { - const T = Parse(`null`) + const T = Syntax(`null`) Assert.IsTrue(TypeGuard.IsNull(T)) }) it('Should parse Number', () => { - const T = Parse(`number`) + const T = Syntax(`number`) Assert.IsTrue(TypeGuard.IsNumber(T)) }) it('Should parse Object 1', () => { - const T = Parse(`{x: boolean, y: number, z: string, }`) + const T = Syntax(`{x: boolean, y: number, z: string, }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 2', () => { - const T = Parse(`{x: boolean; y: number; z: string; }`) + const T = Syntax(`{x: boolean; y: number; z: string; }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 3', () => { - const T = Parse(`{ + const T = Syntax(`{ x: boolean y: number z: string @@ -306,7 +219,7 @@ describe('syntax/Parse', () => { Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 4', () => { - const T = Parse(`{ + const T = Syntax(`{ x: boolean; y: number; z: string; @@ -317,7 +230,7 @@ describe('syntax/Parse', () => { Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Object 5', () => { - const T = Parse(`{ + const T = Syntax(`{ x: boolean, y: number, z: string, @@ -328,51 +241,51 @@ describe('syntax/Parse', () => { Assert.IsTrue(TypeGuard.IsString(T.properties.z)) }) it('Should parse Omit 1', () => { - const T = Parse(`Omit<{ x: boolean, y: number, z: string }, 'z'>`) + const T = Syntax(`Omit<{ x: boolean, y: number, z: string }, 'z'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Omit 2', () => { - const T = Parse(`Omit<{ x: boolean, y: number, z: string }, 'z' | 'y'>`) + const T = Syntax(`Omit<{ x: boolean, y: number, z: string }, 'z' | 'y'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(('y' in T.properties) === false) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Parameters', () => { - const T = Parse(`Parameters<(a: number, b: string) => boolean>`) + const T = Syntax(`Parameters<(a: number, b: string) => boolean>`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(TypeGuard.IsNumber(T.items![0])) Assert.IsTrue(TypeGuard.IsString(T.items![1])) }) it('Should parse Partial', () => { - const T = Parse(`Partial<{ x: boolean, y: number, z: string }>`) + const T = Syntax(`Partial<{ x: boolean, y: number, z: string }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(('required' in T) === false) }) it('Should parse Pick 1', () => { - const T = Parse(`Pick<{ x: boolean, y: number, z: string }, 'x' | 'y'>`) + const T = Syntax(`Pick<{ x: boolean, y: number, z: string }, 'x' | 'y'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Pick 2', () => { - const T = Parse(`Pick<{ x: boolean, y: number, z: string }, 'x'>`) + const T = Syntax(`Pick<{ x: boolean, y: number, z: string }, 'x'>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(('y' in T.properties) === false) Assert.IsTrue(('z' in T.properties) === false) }) it('Should parse Promise', () => { - const T = Parse(`Promise`) + const T = Syntax(`Promise`) Assert.IsTrue(TypeGuard.IsPromise(T)) Assert.IsTrue(TypeGuard.IsNumber(T.item)) }) it('Should parse ReadonlyOptional', () => { - const T = Parse(`{ readonly x?: boolean, readonly y?: number }`) + const T = Syntax(`{ readonly x?: boolean, readonly y?: number }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) @@ -382,7 +295,7 @@ describe('syntax/Parse', () => { Assert.IsTrue(TypeGuard.IsOptional(T.properties.y)) }) it('Should parse Readonly', () => { - const T = Parse(`{ readonly x: boolean, readonly y: number }`) + const T = Syntax(`{ readonly x: boolean, readonly y: number }`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsBoolean(T.properties.x)) Assert.IsTrue(TypeGuard.IsReadonly(T.properties.x)) @@ -390,58 +303,58 @@ describe('syntax/Parse', () => { Assert.IsTrue(TypeGuard.IsReadonly(T.properties.y)) }) it('Should parse Record 1', () => { - const T = Parse(`Record`) + const T = Syntax(`Record`) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(.*)$'])) }) it('Should parse Record 2', () => { - const T = Parse(`Record`) + const T = Syntax(`Record`) Assert.IsTrue(TypeGuard.IsRecord(T)) Assert.IsTrue(TypeGuard.IsNumber(T.patternProperties['^(0|[1-9][0-9]*)$'])) }) it('Should parse Record 3', () => { - const T = Parse(`Record<'x' | 'y', number>`) + const T = Syntax(`Record<'x' | 'y', number>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.x)) Assert.IsTrue(TypeGuard.IsNumber(T.properties.y)) }) it('Should parse Recursive', () => { - const T = Type.Recursive(This => Parse({ This }, `{ id: string, nodes: This[] }`)) + const T = Type.Recursive(This => Syntax({ This }, `{ id: string, nodes: This[] }`)) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(TypeGuard.IsString(T.properties.id)) Assert.IsTrue(TypeGuard.IsArray(T.properties.nodes)) Assert.IsTrue(TypeGuard.IsThis(T.properties.nodes.items)) }) it('Should parse Ref', () => { - const T = Parse('foo') + const T = Syntax('foo') Assert.IsTrue(TypeGuard.IsRef(T)) Assert.IsTrue(T.$ref === 'foo') }) it('Should parse Required', () => { - const T = Parse(`Required<{ x?: boolean, y?: number, z?: string }>`) + const T = Syntax(`Required<{ x?: boolean, y?: number, z?: string }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsEqual(T.required, ['x', 'y', 'z']) }) it('Should parse ReturnType 1', () => { - const T = Parse(`ReturnType<() => { x: 1, y: 2 }>`) + const T = Syntax(`ReturnType<() => { x: 1, y: 2 }>`) Assert.IsTrue(TypeGuard.IsObject(T)) Assert.IsTrue(T.properties.x.const === 1) Assert.IsTrue(T.properties.y.const === 2) }) it('Should parse ReturnType 2', () => { - const T = Parse(`ReturnType`) // generalization issue - Assert.IsTrue(T === undefined) + const T = Syntax(`ReturnType`) // generalization issue + Assert.IsTrue(TypeGuard.IsNever(T)) }) it('Should parse String', () => { - const T = Parse(`string`) + const T = Syntax(`string`) Assert.IsTrue(TypeGuard.IsString(T)) }) it('Should parse Symbol', () => { - const T = Parse(`symbol`) + const T = Syntax(`symbol`) Assert.IsTrue(TypeGuard.IsSymbol(T)) }) it('Should parse Tuple', () => { - const T = Parse(`[0, 1, 2, 3]`) + const T = Syntax(`[0, 1, 2, 3]`) Assert.IsTrue(TypeGuard.IsTuple(T)) Assert.IsTrue(T.items![0].const === 0) Assert.IsTrue(T.items![1].const === 1) @@ -449,32 +362,32 @@ describe('syntax/Parse', () => { Assert.IsTrue(T.items![3].const === 3) }) it('Should parse Uint8Array', () => { - const T = Parse(`Uint8Array`) + const T = Syntax(`Uint8Array`) Assert.IsTrue(TypeGuard.IsUint8Array(T)) }) it('Should parse Undefined', () => { - const T = Parse(`undefined`) + const T = Syntax(`undefined`) Assert.IsTrue(TypeGuard.IsUndefined(T)) }) it('Should parse Union 1', () => { - const T = Parse(`1 | 2`) + const T = Syntax(`1 | 2`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) }) it('Should parse Union 2', () => { - const T = Parse(`1 | (2 | 3)`) + const T = Syntax(`1 | (2 | 3)`) Assert.IsTrue(TypeGuard.IsUnion(T)) Assert.IsTrue(T.anyOf[0].const === 1) Assert.IsTrue(T.anyOf[1].const === 2) Assert.IsTrue(T.anyOf[2].const === 3) }) it('Should parse Unknown', () => { - const T = Parse(`unknown`) + const T = Syntax(`unknown`) Assert.IsTrue(TypeGuard.IsUnknown(T)) }) it('Should parse Void', () => { - const T = Parse(`void`) + const T = Syntax(`void`) Assert.IsTrue(TypeGuard.IsVoid(T)) }) }) diff --git a/tsconfig.json b/tsconfig.json index 34a4b8f2..78605604 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "paths": { "@sinclair/typebox/compiler": ["src/compiler/index.ts"], "@sinclair/typebox/errors": ["src/errors/index.ts"], + "@sinclair/typebox/parser": ["src/parser/index.ts"], "@sinclair/typebox/syntax": ["src/syntax/index.ts"], "@sinclair/typebox/system": ["src/system/index.ts"], "@sinclair/typebox/type": ["src/type/index.ts"],