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 538a99f commit c88678f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 59 deletions.
39 changes: 27 additions & 12 deletions examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,38 @@ import {
Indexer,
} from '@sinclair/typebox'

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

const I = Type.Index(T, Type.Literal('x'))
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 C = Accessor.Union<typeof T['anyOf'], 'x'>
type Z = C['anyOf'][1]
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 P = Z extends TNever ? 1 : 2
type E = Evaluate<M>

type N = Accessor.NeverCheck<C['anyOf']>
type Foo<T extends number[], S = T> =
T extends [infer L extends number, ...infer R extends number[]]
? L extends 0
? []
: Foo<R, S>
: S

const C = Accessor.Union(T.anyOf, 'x')




console.log(C)

83 changes: 36 additions & 47 deletions src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ export const PatternStringExact = `^${PatternString}$`
export function Into<U>(func: () => U): U {
return func()
}
export function Infer<T, U>(T: T, func: (T: T) => U): U {
return func(T)
}
// --------------------------------------------------------------------------
// Helpers
// --------------------------------------------------------------------------
Expand Down Expand Up @@ -2704,72 +2701,63 @@ export namespace Indexer {
// prettier-ignore
export namespace Accessor {
// ----------------------------------------------------------------
// NeverCheck
// Collect
// ----------------------------------------------------------------
export type NeverCheck<T extends TSchema[]> =
export type Collect<T extends TSchema[], K extends PropertyKey> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? L extends TNever
? true
: NeverCheck<R>
: false
export function NeverCheck(T: TSchema[]): boolean {
? [Key<L, K>, ...Collect<R, K>]
: []
export function Collect(T: TSchema[], K: PropertyKey): TSchema[] {
const [L, ...R] = T
return T.length > 0
? TypeGuard.TNever(L)
? true
: NeverCheck(R)
: false
? [Key(L, K), ...Collect(R, K)]
: []
}
// ----------------------------------------------------------------
// Intersect
// ----------------------------------------------------------------
export type IntersectCollect<T extends TSchema[], K extends PropertyKey> =
export type IntersectEvaluate<T extends TSchema[]> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? Key<L, K> extends infer N extends TSchema
? N extends TNever
? [...IntersectCollect<R, K>]
: [N, ...IntersectCollect<R, K>]
? L extends TNever
? [...IntersectEvaluate<R>]
: [L, ...IntersectEvaluate<R>]
: []
: []
function IntersectCollect(T: TSchema[], K: PropertyKey): TSchema[] {
export function IntersectEvaluate(T: TSchema[]): TSchema[] {
const [L, ...R] = T
return T.length > 0
? Infer(Key(L, K), N => {
return TypeGuard.TNever(N)
? [...IntersectCollect(R, K)]
: [N, ...IntersectCollect(R, K)]
})
return T.length > 0
? TypeGuard.TNever(L)
? [...IntersectEvaluate(R)]
: [L, ...IntersectEvaluate(R)]
: []
}
export type Intersect<T extends TSchema[], K extends PropertyKey, C extends TSchema[] = IntersectCollect<T, K>> =
IntersectType.Resolve<C>
export type Intersect<T extends TSchema[], K extends PropertyKey> = (
IntersectType.Resolve<IntersectEvaluate<Collect<T, K>>>
)
export function Intersect(T: TSchema[], K: PropertyKey): TSchema {
const C = IntersectCollect(T, K)
return IntersectType.Resolve(C)
return IntersectType.Resolve(IntersectEvaluate(Collect(T, K)))
}
// ----------------------------------------------------------------
// Union
// ----------------------------------------------------------------
export type UnionCollect<T extends TSchema[], K extends PropertyKey> =
export type UnionEvaluate<T extends TSchema[], S = T> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [Key<L, K>, ...UnionCollect<R, K>]
: []
export type Union<T extends TSchema[], K extends PropertyKey, C extends TSchema[] = UnionCollect<T, K>, N extends boolean = NeverCheck<C>> =
N extends true
? TNever
: TUnion<C>
export function UnionCollect(T: TSchema[], K: PropertyKey): TSchema[] {
? L extends TNever
? []
: UnionEvaluate<R, S>
: S
export function UnionEvaluate(T: TSchema[], S: TSchema[] = T): TSchema[] {
const [L, ...R] = T
return T.length > 0
? [Key(L, K), ...UnionCollect(R, K)]
: []
? TypeGuard.TNever(L)
? []
: UnionEvaluate(R, S)
: S
}
export type Union<T extends TSchema[], K extends PropertyKey> = (
UnionType.Resolve<UnionEvaluate<Collect<T, K>>>
)
export function Union(T: TSchema[], K: PropertyKey): TSchema {
const C = UnionCollect(T, K)
const N = NeverCheck(C)
return N === true
? Type.Never()
: UnionType.Resolve(C)
return UnionType.Resolve(UnionEvaluate(Collect(T, K)))
}
// ----------------------------------------------------------------
// Property
Expand Down Expand Up @@ -2848,8 +2836,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

0 comments on commit c88678f

Please sign in to comment.