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 b90fd6b commit d1f203d
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 35 deletions.
20 changes: 8 additions & 12 deletions examples/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,18 @@
// Accessor
// --------------------------------------------------------------------------

import { Type, Optional, TOptional, TReadonly, TObject, TTuple, TIntersect, TUnion, Kind, TSchema, TypeClone, TypeGuard, ValueGuard, TPropertyKey, SchemaOptions, TProperties, TNever, TRecursive, TArray, Discard, TNumber, TString, TBoolean } from "@sinclair/typebox"

export function Into<T>(func: () => T): T {
return func()
}
import { Type, Static, Distinct, Optional, TOptional, TReadonly, TObject, TTuple, TIntersect, TUnion, Kind, TSchema, TypeClone, TypeGuard, ValueGuard, TPropertyKey, SchemaOptions, TProperties, TNever, TRecursive, TArray, Discard, TNumber, TString, TBoolean } from "@sinclair/typebox"

const T = Type.Object({
x: Type.String(),
y: Type.Union([
Type.Number(),
Type.BigInt()
])
x: Type.Number(),
y: Type.Number(),
z: Type.Number()
})
type T = typeof T

const I = Type.Index(T, Type.KeyOf(T))

type A = Distinct.Resolve<[TString, T]>
const A = Distinct.Resolve([Type.String(), T])
console.log(A)

// ------------------------------------------------------------------
// Accessor
Expand Down
55 changes: 32 additions & 23 deletions src/typebox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2434,31 +2434,40 @@ export namespace TypeClone {
// Distinct
// ------------------------------------------------------------------
// prettier-ignore
export type TDistinctIncludes<T extends TSchema[], C extends TSchema> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? C extends L
? true
: TDistinctIncludes<R, C>
: false
// prettier-ignore
export type TDistinct<T extends TSchema[], Acc extends TSchema[] = []> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? TDistinctIncludes<Acc, L> extends false
? TDistinct<R, [...Acc, L]>
: TDistinct<R, [...Acc]>
: Acc

export namespace Distinct {
function DistinctIncludes(schemas: TSchema[], candidate: TSchema) {
return schemas.find((schema) => TypeExtends.Extends(candidate, schema) === TypeExtendsResult.True) !== undefined
// ----------------------------------------------------------------
// Includes
// ----------------------------------------------------------------
export type Includes<T extends TSchema[], C extends TSchema> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? C extends L
? true
: Includes<R, C>
: false
export function Includes(T: TSchema[], C: TSchema): boolean {
const [L, ...R] = T
return T.length > 0
? TypeExtends.Extends(C, L) === TypeExtendsResult.True
? true
: Includes(R, C)
: false
}
// prettier-ignore
export function Distinct<T extends TSchema[]>(schemas: [...T]): TDistinct<T> {
return schemas.reduce((acc, candidate) => {
return !DistinctIncludes(acc, candidate)
? [...acc, candidate]
: [...acc]
}, [] as TSchema[]) as TDistinct<T>
// ----------------------------------------------------------------
// Resolve
// ----------------------------------------------------------------
export type Resolve<T extends TSchema[], Acc extends TSchema[] = []> =
T extends [infer L extends TSchema, ...infer R extends TSchema[]]
? Includes<Acc, L> extends false
? Resolve<R, [...Acc, L]>
: Resolve<R, [...Acc]>
: Acc
export function Resolve(T: TSchema[], Acc: TSchema[] = []): TSchema[] {
const [L, ...R] = T
return T.length > 0
? Includes(Acc, L) === false
? Resolve(R, [...Acc, L])
: Resolve(R, [...Acc])
: Acc
}
}
// --------------------------------------------------------------------------
Expand Down

0 comments on commit d1f203d

Please sign in to comment.