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 23, 2023
1 parent c88678f commit bad253a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 31 deletions.
104 changes: 74 additions & 30 deletions examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,42 +41,86 @@ import {
IsTemplateLiteralFiniteCheck,
UnionToTuple,
PatternNumber,
Increment,
Accessor,
Indexer,
Assert
} from '@sinclair/typebox'

// export type UnionCollect<T extends TSchema[], K extends PropertyKey> =
// T extends [infer L extends TSchema, ...infer R extends TSchema[]]
// ? [Accessor.Key<L, K>, ...UnionCollect<R, K>]
// : []
// prettier-ignore
export namespace KeyOf {
// ----------------------------------------------------------------
// Intersect
// ----------------------------------------------------------------
export type Intersect<T extends TSchema[]> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [...Resolve<L>, ...Intersect<R>]
: []
export function Intersect(T: TSchema[]): string[] {
const [L, ...R] = T
return T.length > 0
? [...Resolve(L), ...Intersect(R)]
: []
}
// ----------------------------------------------------------------
// Union
// ----------------------------------------------------------------
export type Union<T extends TSchema[]> = []
export function Union(T: TSchema[]): string[] {
return globalThis.Object.getOwnPropertyNames(T)
}
// ----------------------------------------------------------------
// Array
// ----------------------------------------------------------------
export type Properties<T extends TProperties> = UnionToTuple<keyof T>
export function Properties(T: TProperties): string[] {
return globalThis.Object.getOwnPropertyNames(T)
}
// ----------------------------------------------------------------
// Array
// ----------------------------------------------------------------
export type Array<_ extends TSchema> = ['number']
export function Array(T: TProperties): string[] {
return ['number']
}
// ----------------------------------------------------------------
// Tuple
// ----------------------------------------------------------------
export type TupleNext<I extends string[] = []> =
I extends [infer L extends string, ...infer _]
? Increment.Next<L>
: '0'
export type Tuple<T extends TSchema[], I extends string[] = []> =
T extends [infer _, ...infer R extends TSchema[]]
? Tuple<R, [TupleNext<I>, ...I]>
: I
export function Tuple(T: TSchema[]): string[] {
return T.map((_, index) => index.toString()).reverse() // ?
}
// ----------------------------------------------------------------
// Resolve
// ----------------------------------------------------------------
export type Resolve<T extends TSchema> = (
T extends TIntersect<infer S> ? Intersect<S> :
T extends TUnion<infer S> ? Union<S> :
T extends TObject<infer S> ? Properties<S> :
T extends TArray<infer S> ? Array<S> :
T extends TTuple<infer S> ? Tuple<S> :
[]
)
export function Resolve(T: TSchema): string[] {
return []
}
}

export type Collect<T extends TSchema[], K extends PropertyKey> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [Accessor.Key<L, K>, ...Collect<R, K>]
: []
type X = KeyOf.Resolve<TObject<{
x: TNumber,
y: TNumber,
z: TNumber
}>>

export type Evaluate<T extends TSchema[], S = T> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? L extends TNever
? []
: Evaluate<R, S>
: S

type M = Collect<[
TObject<{ x: TString }>,
TObject<{ x: TString }>,
], 'x'>
type A = { x: number } | { x: number }
type K = keyof A

type E = Evaluate<M>

type Foo<T extends number[], S = T> =
T extends [infer L extends number, ...infer R extends number[]]
? L extends 0
? []
: Foo<R, S>
: S





3 changes: 2 additions & 1 deletion examples/next/accessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,9 @@ export namespace Accessor {
// ----------------------------------------------------------------
// Resolve
// ----------------------------------------------------------------
export type Resolve<T extends TSchema, K extends PropertyKey[]> =
export type Resolve<T extends TSchema, K extends PropertyKey[]> = (
UnionType.Resolve<Keys<T, K>>
)
export function Resolve(T: TSchema, K: PropertyKey[]) {
return UnionType.Resolve(Keys(T, K))
}
Expand Down
14 changes: 14 additions & 0 deletions src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2620,6 +2620,20 @@ export namespace IndexerOld {
return [...new Set(Visit(schema, options))]
}
}
// ----------------------------------------------------------------
// Increment
// ----------------------------------------------------------------
// prettier-ignore
export namespace Increment {
export type Base = { m: '9', t: '01', '0': '1', '1': '2', '2': '3', '3': '4', '4': '5', '5': '6', '6': '7', '7': '8', '8': '9', '9': '0' }
export type Reverse<T extends string> = T extends `${infer L}${infer R}` ? `${Reverse<R>}${L}` : T
export type Tick<T extends string, B extends Base> = B[Assert<T, keyof B>]
export type Increment<T extends string, B extends Base> = T extends B['m'] ? B['t'] : T extends `${infer L}${infer R}` ? L extends B['m']
? `${Assert<Tick<L, B>, string>}${Increment<R, B>}`
: `${Assert<Tick<L, B>, string>}${R}`
: never
export type Next<T extends string, B extends Base = Base> = Reverse<Increment<Reverse<T>, B>>
}
// ------------------------------------------------------------------
// Indexer
// ------------------------------------------------------------------
Expand Down

0 comments on commit bad253a

Please sign in to comment.