import { ArrayKeys, Eq, IsAny } from './utils'; import { Type } from './Type'; import { inferArgs } from './inferArgs'; import { Generic, _apply, _Type } from './apply'; import { TypesMap } from './TypesMap'; import { Tuple, ReadonlyTuple, Array, ReadonlyArray } from './free-types'; type ArrayURIs = 'Tuple' | 'ReadonlyTuple' | 'Array' | 'ReadonlyArray'; type Search = _Type | SearchList; type SearchList = _Type[] | Record | Interface; type Interface = { [k: string]: any; } & { [Symbol.toStringTag]?: never; }; declare global { interface SymbolConstructor { readonly toStringTag: unique symbol; } interface Symbol { readonly [Symbol.toStringTag]: string; } var Symbol: SymbolConstructor; } export { unwrap, Unwrapped, Search }; /** Decompose a type into its constituents */ type unwrap = IsAny extends true ? Any : (T extends readonly unknown[] ? From extends _Type | _Type[] ? null : unwrapLists : null) extends infer R extends Unwrapped ? R : _unwrap : From>; type unwrapLists = T extends unknown[] ? any[] extends T ? Unwrapped<'Array', Array, [T[0]]> : Unwrapped<'Tuple', Tuple, T> : readonly any[] extends T ? Unwrapped<'ReadonlyArray', ReadonlyArray, [T[0]]> : Unwrapped<'ReadonlyTuple', ReadonlyTuple, Mutable>; type Mutable = { -readonly [K in keyof T]: T[K]; }; type _unwrap = { [K in keyof From as K extends ArrayKeys ? never : K extends string ? K : never]: From[K] extends _Type ? T extends Generic ? Disambiguate, K & string> : never : never; } extends infer R ? R[keyof R] : never; type Disambiguate = Eq> extends true ? Unwrapped : never; /** The result of unwrapping a type with `unwrap` */ type Unwrapped = { URI: URI; type: T; args: A; }; interface $Any extends Type { type: any; } type Any = Unwrapped<'any', $Any, any>;