UNPKG

@sinclair/typebox

Version:

Json Schema Type Builder with Static Type Resolution for TypeScript

55 lines (54 loc) 6.38 kB
import { type TSchema, SchemaOptions } from '../schema/index.mjs'; import { type TComputed } from '../computed/index.mjs'; import { type TLiteral, type TLiteralValue } from '../literal/index.mjs'; import { type TObject, type TProperties } from '../object/index.mjs'; import { type Assert } from '../helpers/index.mjs'; import { type TNever } from '../never/index.mjs'; import { type TRecursive } from '../recursive/index.mjs'; import { type TIntersect } from '../intersect/index.mjs'; import { TMappedResult, type TMappedKey } from '../mapped/index.mjs'; import { type TUnion } from '../union/index.mjs'; import { type TTuple } from '../tuple/index.mjs'; import { type TArray } from '../array/index.mjs'; import { type TRef } from '../ref/index.mjs'; import { type TIntersectEvaluated } from '../intersect/index.mjs'; import { type TUnionEvaluated } from '../union/index.mjs'; import { type TIndexPropertyKeys } from './indexed-property-keys.mjs'; import { type TIndexFromMappedKey } from './indexed-from-mapped-key.mjs'; import { type TIndexFromMappedResult } from './indexed-from-mapped-result.mjs'; type TFromRest<T extends TSchema[], K extends PropertyKey, Result extends TSchema[] = []> = (T extends [infer L extends TSchema, ...infer R extends TSchema[]] ? TFromRest<R, K, [...Result, Assert<TIndexFromPropertyKey<L, K>, TSchema>]> : Result); type TFromIntersectRest<Types extends TSchema[], Result extends TSchema[] = []> = (Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TNever ? TFromIntersectRest<Right, [...Result]> : TFromIntersectRest<Right, [...Result, Left]> : Result); type TFromIntersect<Types extends TSchema[], Key extends PropertyKey> = (TIntersectEvaluated<TFromIntersectRest<TFromRest<Types, Key>>>); type TFromUnionRest<Types extends TSchema[], Result extends TSchema[] = []> = Types extends [infer Left extends TSchema, ...infer Right extends TSchema[]] ? Left extends TNever ? [] : TFromUnionRest<Right, [Left, ...Result]> : Result; type TFromUnion<Types extends TSchema[], Key extends PropertyKey> = (TUnionEvaluated<TFromUnionRest<TFromRest<Types, Key>>>); type TFromTuple<Types extends TSchema[], Key extends PropertyKey, Result extends TSchema = (Key extends '[number]' ? TUnionEvaluated<Types> : Key extends keyof Types ? Types[Key] extends infer Type extends TSchema ? Type : TNever : TNever)> = Result; type TFromArray<Type extends TSchema, Key extends PropertyKey> = (Key extends '[number]' ? Type : TNever); type AssertPropertyKey<T extends unknown> = Assert<T, string | number>; type TFromProperty<Properties extends TProperties, Key extends PropertyKey, Result extends TSchema = (Key extends keyof Properties ? Properties[Key] : `${AssertPropertyKey<Key>}` extends `${AssertPropertyKey<keyof Properties>}` ? Properties[AssertPropertyKey<Key>] : TNever)> = Result; export type TIndexFromPropertyKey<Type extends TSchema, Key extends PropertyKey> = (Type extends TRecursive<infer S extends TSchema> ? TIndexFromPropertyKey<S, Key> : Type extends TIntersect<infer S extends TSchema[]> ? TFromIntersect<S, Key> : Type extends TUnion<infer S extends TSchema[]> ? TFromUnion<S, Key> : Type extends TTuple<infer S extends TSchema[]> ? TFromTuple<S, Key> : Type extends TArray<infer S extends TSchema> ? TFromArray<S, Key> : Type extends TObject<infer S extends TProperties> ? TFromProperty<S, Key> : TNever); export declare function IndexFromPropertyKey<Type extends TSchema, Key extends PropertyKey>(type: Type, key: Key): TIndexFromPropertyKey<Type, Key>; export type TIndexFromPropertyKeys<Type extends TSchema, PropertyKeys extends PropertyKey[], Result extends TSchema[] = []> = (PropertyKeys extends [infer Left extends PropertyKey, ...infer Right extends PropertyKey[]] ? TIndexFromPropertyKeys<Type, Right, [...Result, Assert<TIndexFromPropertyKey<Type, Left>, TSchema>]> : Result); export declare function IndexFromPropertyKeys<Type extends TSchema, PropertyKeys extends PropertyKey[]>(type: Type, propertyKeys: [...PropertyKeys]): TIndexFromPropertyKeys<Type, PropertyKeys>; type TFromType<Type extends TSchema, PropertyKeys extends PropertyKey[], Result extends TSchema[] = TIndexFromPropertyKeys<Type, PropertyKeys>> = TUnionEvaluated<Result>; type TUnionFromPropertyKeys<PropertyKeys extends PropertyKey[], Result extends TLiteral[] = []> = (PropertyKeys extends [infer Key extends PropertyKey, ...infer Rest extends PropertyKey[]] ? Key extends TLiteralValue ? TUnionFromPropertyKeys<Rest, [...Result, TLiteral<Key>]> : TUnionFromPropertyKeys<Rest, [...Result]> : TUnionEvaluated<Result>); type TResolvePropertyKeys<Key extends TSchema | PropertyKey[]> = Key extends TSchema ? TIndexPropertyKeys<Key> : Key; type TResolveTypeKey<Key extends TSchema | PropertyKey[]> = Key extends PropertyKey[] ? TUnionFromPropertyKeys<Key> : Key; export type TIndex<Type extends TSchema, Key extends TSchema | PropertyKey[], IsTypeRef extends boolean = Type extends TRef ? true : false, IsKeyRef extends boolean = Key extends TRef ? true : false> = (Key extends TMappedResult ? TIndexFromMappedResult<Type, Key> : Key extends TMappedKey ? TIndexFromMappedKey<Type, Key> : [ IsTypeRef, IsKeyRef ] extends [true, true] ? TComputed<'Index', [Type, TResolveTypeKey<Key>]> : [ IsTypeRef, IsKeyRef ] extends [false, true] ? TComputed<'Index', [Type, TResolveTypeKey<Key>]> : [ IsTypeRef, IsKeyRef ] extends [true, false] ? TComputed<'Index', [Type, TResolveTypeKey<Key>]> : TFromType<Type, TResolvePropertyKeys<Key>>); /** `[Json]` Returns an Indexed property type for the given keys */ export declare function Index<Type extends TSchema, Key extends PropertyKey[]>(type: Type, key: readonly [...Key], options?: SchemaOptions): TIndex<Type, Key>; /** `[Json]` Returns an Indexed property type for the given keys */ export declare function Index<Type extends TSchema, Key extends TMappedKey>(type: Type, key: Key, options?: SchemaOptions): TIndex<Type, Key>; /** `[Json]` Returns an Indexed property type for the given keys */ export declare function Index<Type extends TSchema, Key extends TMappedResult>(type: Type, key: Key, options?: SchemaOptions): TIndex<Type, Key>; /** `[Json]` Returns an Indexed property type for the given keys */ export declare function Index<Type extends TSchema, Key extends TSchema>(type: Type, key: Key, options?: SchemaOptions): TIndex<Type, Key>; export {};