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 da152e6 commit d58554c
Show file tree
Hide file tree
Showing 4 changed files with 331 additions and 219 deletions.
273 changes: 146 additions & 127 deletions examples/index.ts
Original file line number Diff line number Diff line change
@@ -1,133 +1,155 @@
import { TypeSystem } from '@sinclair/typebox/system'
import { TypeCompiler } from '@sinclair/typebox/compiler'
import { Value, ValuePointer } from '@sinclair/typebox/value'
import { Type, Static, TSchema, TProperties, TArray, TLiteral, TTemplateLiteral, TypeGuard, TemplateLiteralParser, TemplateLiteralGenerator, TemplateLiteralResolver } from '@sinclair/typebox'
import {
Type,
Static,
TSchema,
TProperties,
TArray,
TLiteral,
TTemplateLiteral,
TypeGuard,
TemplateLiteralParser,
TemplateLiteralGenerator,
TemplateLiteralResolver,
TemplateLiteralFinite,
IsTemplateLiteralFiniteCheck,
KeyResolver,
TOptional,
UnionTypeIsOptional,
} 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<T extends TProperties, K extends PropertyKey> =
K extends keyof T
? [T[K]]
: []
// prettier-ignore
export type TIndexTuple<T extends TSchema[], K extends PropertyKey> =
K extends keyof T
? [T[K]]
: []
// prettier-ignore
export type TIndexArray<T extends TSchema, K extends PropertyKey> =
K extends number
? [T]
: []
// prettier-ignore
export type TIndexIntersect<T extends TSchema[], K extends PropertyKey> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [...TIndexKey<L, K>, ...TIndexIntersect<R, K>]
: []
// prettier-ignore
export type TIndexUnionGather<T extends TSchema[], K extends PropertyKey> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [TIndexKey<L, K>, ...TIndexUnionGather<R, K>]
: []
// prettier-ignore
export type TIndexUnionCheck<T extends TSchema[][]> =
T extends [infer L extends TSchema[], ...infer R extends TSchema[][]]
? L extends []
? false
: TIndexUnionCheck<R>
: true
// prettier-ignore
export type TIndexUnionFinal<T extends TSchema[][]> =
T extends [infer L extends TSchema[], ...infer R extends TSchema[][]]
? [...L, ...TIndexUnionFinal<R>]
: []
// prettier-ignore
export type TIndexUnion<T extends TSchema[], K extends PropertyKey, G extends TSchema[][] = TIndexUnionGather<T, K>, C extends boolean = TIndexUnionCheck<G>> =
C extends true
? TIndexUnionFinal<G>
: []
// prettier-ignore
export type TIndexKey<T extends TSchema, K extends PropertyKey> =
T extends TRecursive<infer S> ? TIndexKey<S, K> :
T extends TIntersect<infer S> ? TIndexIntersect<S, K> :
T extends TUnion<infer S> ? TIndexUnion<S, K> :
T extends TTuple<infer S> ? TIndexTuple<S, K> :
T extends TArray<infer S> ? TIndexArray<S, K> :
T extends TObject<infer S> ? TIndexProperties<S, K> :
[]
// prettier-ignore
export type TIndexKeys<T extends TSchema, K extends PropertyKey[]> =
K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]]
? [...TIndexKey<T, L>, ...TIndexKeys<T, R>]
: []
export type TIndex<T extends TSchema, K extends PropertyKey[], R extends TSchema[] = TIndexKeys<T, K>> = UnionType<R>
const T = Type.Intersect([Type.Object({ x: Type.Optional(Type.Number()) }), Type.Object({ x: Type.Optional(Type.Number()) })])

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 {
const S = Type.Intersect([Type.Number(), Type.Object({ x: Type.Number() })])

}
// ------------------------------------------------------------------
// TIndexer
// ------------------------------------------------------------------
export type TIndexerTemplateLiteral<T extends TTemplateLiteral> = UnionToTuple<Static<T>>
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 ? TIndexerTemplateLiteral<T> :
T extends TUnion<infer S> ? TIndexerUnion<S> :
T extends TLiteral<infer S> ? [S] :
T extends TString ? [string] :
T extends TNumber ? [number] :
T extends TInteger ? [number] :
T extends TBigInt ? [bigint] :
[]

export namespace Indexer {
function TIndexerTemplateLiteral(schema: TUnion<TLiteral[]> | 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 []
}
}
}
type A = Static<typeof S>

const I = Type.Index(T, Type.KeyOf(T))



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({ z: Type.Boolean() })
])
// prettier-ignore
// export type UnionTypeIsOptional<T extends TSchema[]> =
// T extends [infer L extends TSchema, ...infer R extends TSchema[]]
// ? L extends TOptional<L>
// ? UnionTypeIsOptional<R>
// : false
// : true

type X = UnionTypeIsOptional<[
TOptional<TNumber>,
TOptional<TNumber>,
]>

// // ------------------------------------------------------------------
// // TIndex
// // ------------------------------------------------------------------
// // prettier-ignore
// export type TIndexProperties<T extends TProperties, K extends PropertyKey> =
// K extends keyof T
// ? [T[K]]
// : []
// // prettier-ignore
// export type TIndexTuple<T extends TSchema[], K extends PropertyKey> =
// K extends keyof T
// ? [T[K]]
// : []
// // prettier-ignore
// export type TIndexArray<T extends TSchema, K extends PropertyKey> =
// K extends number
// ? [T]
// : []
// // prettier-ignore
// export type TIndexIntersect<T extends TSchema[], K extends PropertyKey> =
// T extends [infer L extends TSchema, ...infer R extends TSchema[]]
// ? [...TIndexKey<L, K>, ...TIndexIntersect<R, K>]
// : []
// // prettier-ignore
// export type TIndexUnionGather<T extends TSchema[], K extends PropertyKey> =
// T extends [infer L extends TSchema, ...infer R extends TSchema[]]
// ? [TIndexKey<L, K>, ...TIndexUnionGather<R, K>]
// : []
// // prettier-ignore
// export type TIndexUnionCheck<T extends TSchema[][]> =
// T extends [infer L extends TSchema[], ...infer R extends TSchema[][]]
// ? L extends []
// ? false
// : TIndexUnionCheck<R>
// : true
// // prettier-ignore
// export type TIndexUnionFinal<T extends TSchema[][]> =
// T extends [infer L extends TSchema[], ...infer R extends TSchema[][]]
// ? [...L, ...TIndexUnionFinal<R>]
// : []
// // prettier-ignore
// export type TIndexUnion<T extends TSchema[], K extends PropertyKey, G extends TSchema[][] = TIndexUnionGather<T, K>, C extends boolean = TIndexUnionCheck<G>> =
// C extends true
// ? TIndexUnionFinal<G>
// : []
// // prettier-ignore
// export type TIndexKey<T extends TSchema, K extends PropertyKey> =
// T extends TRecursive<infer S> ? TIndexKey<S, K> :
// T extends TIntersect<infer S> ? TIndexIntersect<S, K> :
// T extends TUnion<infer S> ? TIndexUnion<S, K> :
// T extends TTuple<infer S> ? TIndexTuple<S, K> :
// T extends TArray<infer S> ? TIndexArray<S, K> :
// T extends TObject<infer S> ? TIndexProperties<S, K> :
// []
// // prettier-ignore
// export type TIndexKeys<T extends TSchema, K extends PropertyKey[]> =
// K extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]]
// ? [...TIndexKey<T, L>, ...TIndexKeys<T, R>]
// : []
// export type TIndex<T extends TSchema, K extends PropertyKey[], R extends TSchema[] = TIndexKeys<T, K>> = UnionType<R>

// 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[] = TKeyResolver<I>>(schema: T, keys: I): TIndex<T, K>
// export function Index(schema: TSchema, keys: unknown): any {

// }

// import {} from '@sinclair/typebox'
// // ------------------------------------------------------------------
// // TIndexer
// // ------------------------------------------------------------------
// export type TKeyResolverTemplateLiteral<T extends TTemplateLiteral, F = IsTemplateLiteralFiniteCheck<T>> =
// F extends true
// ? UnionToTuple<Static<T>>
// : []
// export type TKeyResolverUnion<T extends TSchema[]> =
// T extends [infer L extends TSchema, ...infer R extends TSchema[]]
// ? [...TKeyResolver<L>, ...TKeyResolverUnion<R>]
// : []
// // prettier-ignore
// export type TKeyResolver<T extends TSchema> =
// T extends TTemplateLiteral ? TKeyResolverTemplateLiteral<T> :
// T extends TUnion<infer S> ? TKeyResolverUnion<S> :
// T extends TLiteral<infer S> ? [S] :
// T extends TString ? [] :
// T extends TNumber ? [] :
// T extends TInteger ? [] :
// T extends TBigInt ? [] :
// []

// const T = Type.TemplateLiteral('a${a|b}${string}')
// const S = KeyResolver.ResolveKeys(T, { includePatterns: false })

// console.log(S, 1)

// console.log(S)

// const E = Type.TemplateLiteral('a${string}')
// type E = TKeyResolver<typeof E>

// const R = TemplateLiteralResolver.Resolve(A)
// console.log(R)

// const S = Type.Intersect([
// Type.Object({ x: Type.Number() }),
// Type.Object({ y: Type.String() }),
// Type.Object({ z: Type.Boolean() })
// ])

// const T = Type.Object({
// x: Type.Object({
Expand All @@ -139,7 +161,6 @@ const S = Type.Intersect([

// type T = Static<typeof T>


// type A = TObject<{ x: TNumber }>
// type B = TObject<{ x: TString }>
// type C = TIntersect<[A, B]>
Expand All @@ -151,12 +172,10 @@ const S = Type.Intersect([

// type S = TIndex<Z, [1]>


// type Q = Array<{ x: 1 }>

// type U = Q[number]





export function Resolve(T: TObject<{}>, arg1: {}) {
throw new Error('Function not implemented.')
}
14 changes: 7 additions & 7 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@
"ajv-formats": "^2.1.1",
"mocha": "^9.2.2",
"prettier": "^2.7.1",
"typescript": "^5.3.2"
"typescript": "^5.4.0-dev.20231122"
}
}
Loading

0 comments on commit d58554c

Please sign in to comment.