Skip to content

Commit

Permalink
Reimplement Index Types
Browse files Browse the repository at this point in the history
  • Loading branch information
sinclairzx81 committed Nov 22, 2023
1 parent 108ecdf commit c0d2a1d
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 9 deletions.
87 changes: 79 additions & 8 deletions examples/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,89 @@
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 } from '@sinclair/typebox'
import { TObject, TUnion, TIntersect, TString, TNumber, TBoolean, TNever, TTuple, UnionType, TRecursive } from '@sinclair/typebox'
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'

// ------------------------------------------------------------------
// TemplateLiteralFinite
// ------------------------------------------------------------------
// prettier-ignore
export type IsTemplateLiteralFiniteCheck<T> =
T extends TTemplateLiteral<infer S> ? IsTemplateLiteralFiniteRest<S> :
T extends TUnion<infer S> ? IsTemplateLiteralFiniteRest<S> :
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 TTemplateLiteralKind[]> =
T extends [infer L extends TTemplateLiteralKind, ...infer R extends TTemplateLiteralKind[]]
? IsTemplateLiteralFiniteCheck<L> extends false
? false
: IsTemplateLiteralFiniteRest<R>
: true
// prettier-ignore
export type IsTemplateLiteralFinite<T extends TTemplateLiteralKind> =
T extends TTemplateLiteral<infer U>
? IsTemplateLiteralFiniteRest<U>
: false

// ------------------------------------------------------------------
// TemplateLiteralUnion
// ------------------------------------------------------------------
// prettier-ignore
export type TTemplateLiteralKind =
| TUnion
| TLiteral
| TInteger
| TTemplateLiteral
| TNumber
| TBigInt
| TString
| TBoolean
| TNever
// prettier-ignore
export type TTemplateLiteralConst<T, Acc extends string> =
T extends TUnion<infer U> ? { [K in keyof U]: TTemplateLiteralUnion<Assert<[U[K]], TTemplateLiteralKind[]>, Acc> }[number] :
T extends TTemplateLiteral ? `${Static<T>}` :
T extends TLiteral<infer U> ? `${U}` :
T extends TString ? `${string}` :
T extends TNumber ? `${number}` :
T extends TBigInt ? `${bigint}` :
T extends TBoolean ? `${boolean}` :
never
// prettier-ignore
export type TTemplateLiteralUnion<T extends TTemplateLiteralKind[], Acc extends string = ''> =
T extends [infer L, ...infer R] ? `${TTemplateLiteralConst<L, Acc>}${TTemplateLiteralUnion<Assert<R, TTemplateLiteralKind[]>, Acc>}` :
Acc

// export type TTemplateLiteralKind = TUnion | TLiteral | TInteger | TTemplateLiteral | TNumber | TBigInt | TString | TBoolean | TNever
// ------------------------------------------------------------------
// TIndexer
// ------------------------------------------------------------------
export type EmptyString = ''

// prettier-ignore
export type TIndexerUnion<T extends TSchema[]> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [...TIndexer<L>, ...TIndexerUnion<R>]
: []
// prettier-ignore
export type TIndexer<T extends TSchema> =
T extends TTemplateLiteral<infer S> ? TTemplateLiteralUnion<S> :
T extends TUnion<infer S> ? TIndexerUnion<S> :
T extends TLiteral<infer S> ? [S] :
T extends TString ? [string] :
T extends TNumber ? [string] :
T extends TNumber ? [number] :
[]

const T = Type.TemplateLiteral('a${1|2|3}')

type Ss = TIndexer<typeof T>

// ------------------------------------------------------------------
// TIndex
// ------------------------------------------------------------------
Expand Down Expand Up @@ -81,15 +145,22 @@ export type TIndexKeys<T extends TSchema, K extends PropertyKey[]> =
: []
export type TIndex<T extends TSchema, K extends PropertyKey[], R extends TSchema[] = TIndexKeys<T, K>> = UnionType<R>

type A = TIndexer<TUnion<[TLiteral<'hello'>, TLiteral<'hello1'>, TString]>>
export function Index<T extends TSchema, K extends string[]>(schema: T, keys: [...K]): TIndex<T, K>
export function Index<T extends TSchema, I extends TSchema, K extends PropertyKey[] = TIndexer<I>>(schema: T, keys: I): TIndex<T, K>
export function Index(schema: TSchema, keys: unknown): any {

export function Index<T extends TSchema, I extends TSchema, K extends PropertyKey[] = TIndexer<I>>(schema: T, keys: I): TIndex<T, K> {
throw 1
}

const T = Type.Array(Type.String())
const S = Type.Intersect([
Type.Object({ x: Type.Number() }),
Type.Object({ y: Type.String() })
])

const A = Type.TemplateLiteral('${x|y}')

type A = TIndexer<typeof A>

const I = Index(T, Type.KeyOf(T))
const I = Index(S, Type.TemplateLiteral('${x|y}'))

type S = Array<string>

Expand Down
2 changes: 1 addition & 1 deletion src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ export type TTemplateLiteralConst<T, Acc extends string> =
T extends TBoolean ? `${boolean}` :
never
// prettier-ignore
export type TTemplateLiteralUnion<T extends TTemplateLiteralKind[], Acc extends string> =
export type TTemplateLiteralUnion<T extends TTemplateLiteralKind[], Acc extends string = ''> =
T extends [infer L, ...infer R] ? `${TTemplateLiteralConst<L, Acc>}${TTemplateLiteralUnion<Assert<R, TTemplateLiteralKind[]>, Acc>}` :
Acc
export type TTemplateLiteralKeyRest<T extends TTemplateLiteral> = Assert<UnionToTuple<Static<T>>, TPropertyKey[]>
Expand Down

0 comments on commit c0d2a1d

Please sign in to comment.