From c88678f232d03d81a95e82bb6713527b5d601955 Mon Sep 17 00:00:00 2001 From: sinclair Date: Fri, 24 Nov 2023 00:46:07 +0900 Subject: [PATCH] Reimplement Index Types --- examples/index.ts | 39 +++++++++++++++------- src/typebox.ts | 83 ++++++++++++++++++++--------------------------- 2 files changed, 63 insertions(+), 59 deletions(-) diff --git a/examples/index.ts b/examples/index.ts index 47592631..bf7b2b1f 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -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 [infer L extends TSchema, ...infer R extends TSchema[]] +// ? [Accessor.Key, ...UnionCollect] +// : [] -const I = Type.Index(T, Type.Literal('x')) +export type Collect = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? [Accessor.Key, ...Collect] + : [] -type C = Accessor.Union -type Z = C['anyOf'][1] +export type Evaluate = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? L extends TNever + ? [] + : Evaluate + : S + +type M = Collect<[ + TObject<{ x: TString }>, + TObject<{ x: TString }>, +], 'x'> -type P = Z extends TNever ? 1 : 2 +type E = Evaluate -type N = Accessor.NeverCheck +type Foo = + T extends [infer L extends number, ...infer R extends number[]] + ? L extends 0 + ? [] + : Foo + : S -const C = Accessor.Union(T.anyOf, 'x') + -console.log(C) - diff --git a/src/typebox.ts b/src/typebox.ts index a6e649f6..9efa014a 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -49,9 +49,6 @@ export const PatternStringExact = `^${PatternString}$` export function Into(func: () => U): U { return func() } -export function Infer(T: T, func: (T: T) => U): U { - return func(T) -} // -------------------------------------------------------------------------- // Helpers // -------------------------------------------------------------------------- @@ -2704,72 +2701,63 @@ export namespace Indexer { // prettier-ignore export namespace Accessor { // ---------------------------------------------------------------- - // NeverCheck + // Collect // ---------------------------------------------------------------- - export type NeverCheck = + export type Collect = T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? L extends TNever - ? true - : NeverCheck - : false - export function NeverCheck(T: TSchema[]): boolean { + ? [Key, ...Collect] + : [] + 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 = + export type IntersectEvaluate = T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? Key extends infer N extends TSchema - ? N extends TNever - ? [...IntersectCollect] - : [N, ...IntersectCollect] + ? L extends TNever + ? [...IntersectEvaluate] + : [L, ...IntersectEvaluate] : [] - : [] - 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> = - IntersectType.Resolve + export type Intersect = ( + IntersectType.Resolve>> + ) 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 = + export type UnionEvaluate = T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? [Key, ...UnionCollect] - : [] - export type Union, N extends boolean = NeverCheck> = - N extends true - ? TNever - : TUnion - export function UnionCollect(T: TSchema[], K: PropertyKey): TSchema[] { + ? L extends TNever + ? [] + : UnionEvaluate + : 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 = ( + UnionType.Resolve>> + ) 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 @@ -2848,8 +2836,9 @@ export namespace Accessor { // ---------------------------------------------------------------- // Resolve // ---------------------------------------------------------------- - export type Resolve = + export type Resolve = ( UnionType.Resolve> + ) export function Resolve(T: TSchema, K: PropertyKey[]) { return UnionType.Resolve(Keys(T, K)) }