From bad253a86d9ec79a091b3e55a3701544c1fdd48a Mon Sep 17 00:00:00 2001 From: sinclair Date: Fri, 24 Nov 2023 01:52:45 +0900 Subject: [PATCH] Reimplement Index Types --- examples/index.ts | 104 +++++++++++++++++++++++++++----------- examples/next/accessor.ts | 3 +- src/typebox.ts | 14 +++++ 3 files changed, 90 insertions(+), 31 deletions(-) diff --git a/examples/index.ts b/examples/index.ts index bf7b2b1f1..75311d1d3 100644 --- a/examples/index.ts +++ b/examples/index.ts @@ -41,42 +41,86 @@ import { IsTemplateLiteralFiniteCheck, UnionToTuple, PatternNumber, + Increment, Accessor, Indexer, + Assert } from '@sinclair/typebox' -// export type UnionCollect = -// T extends [infer L extends TSchema, ...infer R extends TSchema[]] -// ? [Accessor.Key, ...UnionCollect] -// : [] +// prettier-ignore +export namespace KeyOf { + // ---------------------------------------------------------------- + // Intersect + // ---------------------------------------------------------------- + export type Intersect = + T extends [infer L extends TSchema, ...infer R extends TSchema[]] + ? [...Resolve, ...Intersect] + : [] + export function Intersect(T: TSchema[]): string[] { + const [L, ...R] = T + return T.length > 0 + ? [...Resolve(L), ...Intersect(R)] + : [] + } + // ---------------------------------------------------------------- + // Union + // ---------------------------------------------------------------- + export type Union = [] + export function Union(T: TSchema[]): string[] { + return globalThis.Object.getOwnPropertyNames(T) + } + // ---------------------------------------------------------------- + // Array + // ---------------------------------------------------------------- + export type Properties = UnionToTuple + 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 [infer L extends string, ...infer _] + ? Increment.Next + : '0' + export type Tuple = + T extends [infer _, ...infer R extends TSchema[]] + ? Tuple, ...I]> + : I + export function Tuple(T: TSchema[]): string[] { + return T.map((_, index) => index.toString()).reverse() // ? + } + // ---------------------------------------------------------------- + // Resolve + // ---------------------------------------------------------------- + export type Resolve = ( + T extends TIntersect ? Intersect : + T extends TUnion ? Union : + T extends TObject ? Properties : + T extends TArray ? Array : + T extends TTuple ? Tuple : + [] + ) + export function Resolve(T: TSchema): string[] { + return [] + } +} -export type Collect = - T extends [infer L extends TSchema, ...infer R extends TSchema[]] - ? [Accessor.Key, ...Collect] - : [] +type X = KeyOf.Resolve> -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 A = { x: number } | { x: number } +type K = keyof A -type E = Evaluate - -type Foo = - T extends [infer L extends number, ...infer R extends number[]] - ? L extends 0 - ? [] - : Foo - : S - - - diff --git a/examples/next/accessor.ts b/examples/next/accessor.ts index 73918379b..b52626eb8 100644 --- a/examples/next/accessor.ts +++ b/examples/next/accessor.ts @@ -105,8 +105,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)) } diff --git a/src/typebox.ts b/src/typebox.ts index 9efa014ae..8c9389c5c 100644 --- a/src/typebox.ts +++ b/src/typebox.ts @@ -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 `${infer L}${infer R}` ? `${Reverse}${L}` : T + export type Tick = B[Assert] + export type Increment = T extends B['m'] ? B['t'] : T extends `${infer L}${infer R}` ? L extends B['m'] + ? `${Assert, string>}${Increment}` + : `${Assert, string>}${R}` + : never + export type Next = Reverse, B>> +} // ------------------------------------------------------------------ // Indexer // ------------------------------------------------------------------