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 24, 2023
1 parent 9c885de commit d5f5d53
Show file tree
Hide file tree
Showing 2 changed files with 168 additions and 134 deletions.
144 changes: 91 additions & 53 deletions examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,103 +51,140 @@ import {
// prettier-ignore
export namespace KeyResolver {
// ----------------------------------------------------------------
// Intersect
// Collect
// ----------------------------------------------------------------
export type Intersect<T extends TSchema[]> = (
export type Collect<T extends TSchema[]> = (
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [...Resolve<L>, ...Intersect<R>]
? [Resolve<L>, ...Collect<R>]
: []
)
export function Intersect<T extends TSchema[]>(T: [...T]): Intersect<T> {
export function Collect<T extends TSchema[]>(T: [...T]): Collect<T> {
const [L, ...R] = T
return (
T.length > 0
? [...Resolve(L), ...Intersect(R)]
? [Resolve(L), ...Collect(R)]
: []
) as Intersect<T>
) as Collect<T>
}
// ----------------------------------------------------------------
// UnionKeyIn
// Includes
// ----------------------------------------------------------------
export type UnionKeyIn<T extends PropertyKey[], S extends PropertyKey> = (
export type Includes<T extends PropertyKey[], S extends PropertyKey> = (
T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]]
? S extends L
? true
: UnionKeyIn<R, S>
: Includes<R, S>
: false
)
export function UnionKeyIn<T extends PropertyKey[], S extends PropertyKey>(T: [...T], S: S) {
export function Includes<T extends PropertyKey[], S extends PropertyKey>(T: [...T], S: S) {
return (
T.includes(S)
) as UnionKeyIn<T, S>
) as Includes<T, S>
}
// ----------------------------------------------------------------
// UnionKeysIn
// IntersectDistinct
// ----------------------------------------------------------------
export type UnionKeysIn<T extends PropertyKey[], S extends PropertyKey[]> = (
export type IntersectDistinct<T extends PropertyKey[], S extends PropertyKey[]> = (
T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]]
? UnionKeyIn<S, L> extends true
? [L, ...UnionKeysIn<R, S>]
: [...UnionKeysIn<R, S>]
: []
? Includes<S, L> extends true
? [...IntersectDistinct<R, S>]
: [L, ...IntersectDistinct<R, S>]
: S
)
export function UnionKeysIn<T extends PropertyKey[], S extends PropertyKey[]>(T: [...T], S: [...S]): UnionKeysIn<T, S> {
export function IntersectDistinct<T extends PropertyKey[], S extends PropertyKey[]>(T: [...T], S: [...S]): IntersectDistinct<T, S> {
const [L, ...R] = T
return (
T.length > 0
? UnionKeyIn(S, L) === true
? [L, ...UnionKeysIn(R, S)]
: [...UnionKeysIn(R, S)]
: []
) as UnionKeysIn<T, S>
? Includes(S, L) === true
? [...IntersectDistinct(R, S)]
: [L, ...IntersectDistinct(R, S)]
: S
) as IntersectDistinct<T, S>
}
// ----------------------------------------------------------------
// UnionKeys
// IntersectIntersection
// ----------------------------------------------------------------
export type UnionKeys<T extends PropertyKey[][]> = (
export type IntersectIntersection<T extends PropertyKey[][]> = (
T extends [infer L extends PropertyKey[]]
? L
: T extends [infer L extends PropertyKey[], ...infer R extends PropertyKey[][]]
? UnionKeysIn<L, UnionKeys<R>>
? IntersectDistinct<L, IntersectIntersection<R>>
: []
)
export function UnionKeys<T extends PropertyKey[][]>(T: [...T]): UnionKeys<T> {
export function IntersectIntersection<T extends PropertyKey[][]>(T: [...T]): IntersectIntersection<T> {
return (
T.length === 1
? T[0]
: Into(() => {
const [L, ...R] = T
return L.length > 0
? UnionKeysIn(L, UnionKeys(R))
? IntersectDistinct(L, IntersectIntersection(R))
: []
})
) as UnionKeys<T>
) as IntersectIntersection<T>
}
// ----------------------------------------------------------------
// UnionCollect
// Intersect
// ----------------------------------------------------------------
export type UnionCollect<T extends TSchema[]> = (
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? [Resolve<L>, ...UnionCollect<R>]
export type Intersect<T extends TSchema[], C extends PropertyKey[][] = Collect<T>> = (
IntersectIntersection<C>
)
export function Intersect<T extends TSchema[]>(T: [...T], C = Collect(T)): Intersect<T> {
return (
IntersectIntersection(C as PropertyKey[][]) as Intersect<T>
)
}
// ----------------------------------------------------------------
// UnionDistinct
// ----------------------------------------------------------------
export type UnionDistinct<T extends PropertyKey[], S extends PropertyKey[]> = (
T extends [infer L extends PropertyKey, ...infer R extends PropertyKey[]]
? Includes<S, L> extends true
? [L, ...UnionDistinct<R, S>]
: [...UnionDistinct<R, S>]
: []
)
export function UnionCollect<T extends TSchema[]>(T: [...T]): UnionCollect<T> {
export function UnionDistinct<T extends PropertyKey[], S extends PropertyKey[]>(T: [...T], S: [...S]): UnionDistinct<T, S> {
const [L, ...R] = T
return (
T.length > 0
? [Resolve(L), ...UnionCollect(R)]
? Includes(S, L) === true
? [L, ...UnionDistinct(R, S)]
: [...UnionDistinct(R, S)]
: []
) as UnionDistinct<T, S>
}
// ----------------------------------------------------------------
// UnionIntersection
// ----------------------------------------------------------------
export type UnionIntersection<T extends PropertyKey[][]> = (
T extends [infer L extends PropertyKey[]]
? L
: T extends [infer L extends PropertyKey[], ...infer R extends PropertyKey[][]]
? UnionDistinct<L, UnionIntersection<R>>
: []
) as UnionCollect<T>
)
export function UnionIntersection<T extends PropertyKey[][]>(T: [...T]): UnionIntersection<T> {
return (
T.length === 1
? T[0]
: Into(() => {
const [L, ...R] = T
return L.length > 0
? UnionDistinct(L, UnionIntersection(R))
: []
})
) as UnionIntersection<T>
}
// ----------------------------------------------------------------
// Union
// ----------------------------------------------------------------
export type Union<T extends TSchema[], C extends PropertyKey[][] = UnionCollect<T>> = (
UnionKeys<C>
export type Union<T extends TSchema[], C extends PropertyKey[][] = Collect<T>> = (
UnionIntersection<C>
)
export function Union<T extends TSchema[]>(T: [...T], C = UnionCollect(T)): Union<T> {
export function Union<T extends TSchema[]>(T: [...T], C = Collect(T)): Union<T> {
return (
UnionKeys(C as PropertyKey[][]) as Union<T>
UnionIntersection(C as PropertyKey[][]) as Union<T>
)
}
// ----------------------------------------------------------------
Expand Down Expand Up @@ -240,25 +277,26 @@ export namespace KeyResolver {
}
}

const A = KeyResolver.ResolvePattern(Type.Intersect([
Type.Record(Type.Number(), Type.Number()),
const A = KeyResolver.Intersect([
Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number()
})
]))
z: Type.Number(),
}),
Type.Object({
x: Type.Number(),
y: Type.Number(),
z: Type.Number(),
}),

const B = KeyResolver.Union([
Type.Object({ x: Type.Number(), y: Type.Number() }),
Type.Object({ x: Type.Number(), y: Type.Number() })
Type.Record(Type.Number(), Type.Number()),
])

console.log(A)

// const B = KeyResolver.Resolve(Type.Union([
// Type.Object({ x: Type.Number(), y: Type.Number() }),
// Type.Object({ x: Type.Number(), z: Type.Number() }),
// ]))






// console.log(B)
Loading

0 comments on commit d5f5d53

Please sign in to comment.