diff --git a/examples/index.ts b/examples/index.ts index 953bc060c..de5058a87 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -1,184 +1,143 @@ import { TypeSystem } from '@sinclair/typebox/system' import { TypeCompiler } from '@sinclair/typebox/compiler' import { Value, ValuePointer } from '@sinclair/typebox/value' -import { Type, TypeGuard, Kind, Static, TSchema, TProperties, TArray, TLiteral, TTemplateLiteral } from '@sinclair/typebox' -import { TObject, TUnion, TInteger, TBigInt, TIntersect, TString, TNumber, TBoolean, TNever, TTuple, UnionType, TRecursive } from '@sinclair/typebox' - -export type EmptyString = '' - -export type Filter = - T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? L extends U ? [L, ...Filter] : Filter - : [] -// ------------------------------------------------------------------ -// TemplateLiteralFinite -// ------------------------------------------------------------------ -// prettier-ignore -export type IsTemplateLiteralFiniteCheck = - T extends TTemplateLiteral ? IsTemplateLiteralFiniteRest : - T extends TUnion ? IsTemplateLiteralFiniteRest : - T extends TString ? false : - T extends TBoolean ? false : - T extends TNumber ? false : - T extends TInteger ? false : - T extends TBigInt ? false : - T extends TLiteral ? true : - false -// prettier-ignore -export type IsTemplateLiteralFiniteRest = - T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] - ? IsTemplateLiteralFiniteCheck extends false - ? false - : IsTemplateLiteralFiniteRest - : true -// prettier-ignore -export type IsTemplateLiteralFinite = - T extends TTemplateLiteral - ? IsTemplateLiteralFiniteRest - : false -// ------------------------------------------------------------------ -// TemplateLiteralRest -// ------------------------------------------------------------------ -// prettier-ignore -export type TTemplateLiteralKind = - | TUnion - | TLiteral - | TInteger - | TTemplateLiteral - | TNumber - | TBigInt - | TString - | TBoolean - | TNever - -// prettier-ignore -export type TTemplateLiteralUnion = - T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] - ? `${TTemplateLiteralString}` | `${TTemplateLiteralUnion}` - : '' -// prettier-ignore -export type TTemplateLiteralString = - T extends TTemplateLiteral ? `${TTemplateLiteralRest}` : - T extends TUnion ? TTemplateLiteralUnion : - T extends TLiteral ? `${S}` : - T extends TString ? `${string}` : - T extends TInteger ? `${number}` : - T extends TNumber ? `${number}` : - T extends TBigInt ? `${bigint}` : - T extends TBoolean ? `${boolean}` : - '' -// prettier-ignore -export type TTemplateLiteralRest = - T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]] - ? `${TTemplateLiteralString}${TTemplateLiteralRest}` - : '' - -const T = Type.TemplateLiteral('a${1|2|3}z') - -type Map = T extends TTemplateLiteral ? TTemplateLiteralRest : '' - -type Q = Map - -type H = Static - -type X = ['A', 'B', 'C'] - -// ------------------------------------------------------------------ -// TIndexer -// ------------------------------------------------------------------ -// prettier-ignore -export type TIndexerUnion = - T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? [...TIndexer, ...TIndexerUnion] - : [] -// prettier-ignore -export type TIndexer = - T extends TTemplateLiteral ? TTemplateLiteralRest : - T extends TUnion ? TIndexerUnion : - T extends TLiteral ? [S] : - T extends TString ? [string] : - T extends TNumber ? [number] : - [] +import { Type, Static, TSchema, TProperties, TArray, TLiteral, TTemplateLiteral, TypeGuard, TemplateLiteralParser, TemplateLiteralGenerator, TemplateLiteralResolver } from '@sinclair/typebox' +import { TObject, TUnion, UnionToTuple, TInteger, TBigInt, TIntersect, TString, TNumber, TBoolean, TNever, TTuple, UnionType, TRecursive } from '@sinclair/typebox' // ------------------------------------------------------------------ // TIndex // ------------------------------------------------------------------ // prettier-ignore -export type TIndexProperties = - K extends keyof T - ? [T[K]] +export type TIndexProperties = + K extends keyof T + ? [T[K]] : [] // prettier-ignore -export type TIndexTuple = - K extends keyof T - ? [T[K]] +export type TIndexTuple = + K extends keyof T + ? [T[K]] : [] // prettier-ignore -export type TIndexArray = - K extends number - ? [T] +export type TIndexArray = + K extends number + ? [T] : [] // prettier-ignore -export type TIndexIntersect = - T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? [...TIndexKey, ...TIndexIntersect] +export type TIndexIntersect = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? [...TIndexKey, ...TIndexIntersect] : [] // prettier-ignore -export type TIndexUnionGather = - T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? [TIndexKey, ...TIndexUnionGather] +export type TIndexUnionGather = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? [TIndexKey, ...TIndexUnionGather] : [] // prettier-ignore -export type TIndexUnionCheck = - T extends [infer L extends TSchema[], ...infer R extends TSchema[][]] - ? L extends [] - ? false - : TIndexUnionCheck +export type TIndexUnionCheck = + T extends [infer L extends TSchema[], ...infer R extends TSchema[][]] + ? L extends [] + ? false + : TIndexUnionCheck : true // prettier-ignore -export type TIndexUnionFinal = - T extends [infer L extends TSchema[], ...infer R extends TSchema[][]] - ? [...L, ...TIndexUnionFinal] +export type TIndexUnionFinal = + T extends [infer L extends TSchema[], ...infer R extends TSchema[][]] + ? [...L, ...TIndexUnionFinal] : [] // prettier-ignore -export type TIndexUnion, C extends boolean = TIndexUnionCheck> = - C extends true - ? TIndexUnionFinal +export type TIndexUnion, C extends boolean = TIndexUnionCheck> = + C extends true + ? TIndexUnionFinal : [] // prettier-ignore -export type TIndexKey = +export type TIndexKey = T extends TRecursive ? TIndexKey : - T extends TIntersect ? TIndexIntersect : + T extends TIntersect ? TIndexIntersect : T extends TUnion ? TIndexUnion : T extends TTuple ? TIndexTuple : T extends TArray ? TIndexArray : T extends TObject ? TIndexProperties : [] // prettier-ignore -export type TIndexKeys = - K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] - ? [...TIndexKey, ...TIndexKeys] +export type TIndexKeys = + K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]] + ? [...TIndexKey, ...TIndexKeys] : [] export type TIndex> = UnionType export function Index(schema: T, keys: [...K]): TIndex -export function Index>(schema: T, keys: I): TIndex +export function Index>(schema: T, keys: I): TIndex export function Index(schema: TSchema, keys: unknown): any { } +// ------------------------------------------------------------------ +// TIndexer +// ------------------------------------------------------------------ +export type TIndexerTemplateLiteral = UnionToTuple> +export type TIndexerUnion = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? [...TIndexer, ...TIndexerUnion] + : [] +// prettier-ignore +export type TIndexer = + T extends TTemplateLiteral ? TIndexerTemplateLiteral : + T extends TUnion ? TIndexerUnion : + T extends TLiteral ? [S] : + T extends TString ? [string] : + T extends TNumber ? [number] : + T extends TInteger ? [number] : + T extends TBigInt ? [bigint] : + [] + +export namespace Indexer { + function TIndexerTemplateLiteral(schema: TUnion | TString | TNever): string[] { + switch(true) { + case TypeGuard.TUnionLiteral(schema): return schema.anyOf.map(schema => schema.const.toString()) + case TypeGuard.TString(schema): return [`{string}`] + default: return [] + } + } + function TIndexerUnion(schemas: TSchema[]): string[] { + const [L, R] = [schemas.slice(0, 1), ...schemas.slice(1)] + return [] + } + function Visit(schema: TSchema, keys: string): string[] { + switch (true) { + case TypeGuard.TTemplateLiteral(schema): return TIndexerTemplateLiteral(TemplateLiteralResolver.Resolve(schema)) + case TypeGuard.TUnion(schema): return TIndexerUnion(schema.anyOf) + case TypeGuard.TLiteral(schema): return [schema.const.toString()] + case TypeGuard.TString(schema): return ['{string}'] + case TypeGuard.TNumber(schema): return ['{number}'] + case TypeGuard.TInteger(schema): return ['{number}'] + case TypeGuard.TBigInt(schema): return ['{bigint}'] + default: return [] + } + } +} + + + + +const A = Type.TemplateLiteral('a${1|2|3}') + +const R = TemplateLiteralResolver.Resolve(A) +console.log(R) const S = Type.Intersect([ Type.Object({ x: Type.Number() }), - Type.Object({ y: Type.String() }) + Type.Object({ y: Type.String() }), + Type.Object({ z: Type.Boolean() }) ]) -const A = Type.TemplateLiteral('${x|y}') - -type A = TIndexer - -const I = Index(S, Type.TemplateLiteral('${x|y}')) +// const T = Type.Object({ +// x: Type.Object({ +// y: Type.Object({ +// i: Index(S, Type.TemplateLiteral('${x|a}')) +// }) +// }) +// }) -type S = Array +// type T = Static // type A = TObject<{ x: TNumber }> diff --git a/src/typebox.ts b/src/typebox.ts index 8bc1a38bd..be90cb8b3 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -2593,7 +2593,7 @@ export namespace TemplateLiteralPattern { // -------------------------------------------------------------------------------------- export namespace TemplateLiteralResolver { /** Resolves a template literal as a TUnion */ - export function Resolve(template: TTemplateLiteral): TString | TUnion | TLiteral { + export function Resolve(template: TTemplateLiteral): TNever | TString | TUnion { const expression = TemplateLiteralParser.ParseExact(template.pattern) if (!TemplateLiteralFinite.Check(expression)) return Type.String() const literals = [...TemplateLiteralGenerator.Generate(expression)].map((value) => Type.Literal(value))