import type { IsBrand } from './brand'; import type { IsIncludeUndefined } from './undefined'; /** * Entry pair that `Object.entries` returns. */ type EntryPair = [key: keyof Type, value: Values]; /** * Alias for type any (to suppress the @typescript-eslint/no-explicit-any rule). */ export type Any = any; /** * Returns the type of instance params. */ export type GetParamsType = Class extends { ['__PARAMS_KEY']: unknown; } ? Normalize : never; /** * Returns `true` if type is an array (or tuple) of given element's type, and `false` otherwise. * `IsArray<[]>` = `true`. * `IsArray<[true, false]>` = `true`. * `IsArray` = `true`. * `IsArray<[1, 2], string>` = `false`. * `IsArray` = `true`. */ export type IsArray = Type extends readonly Element[] ? true : false; /** * Returns a copy of the object type with mutable properties. * `Mutable<{readonly foo: string}>` = `{foo: string}`. */ export type Mutable = { -readonly [Key in keyof Type]: Type[Key]; }; /** * Normalizes intersection of types. * `Normalize<{foo: string} & {bar: number}>` = `{foo: string, bar: number}`. */ export type Normalize = keyof Type extends never ? Type : IsBrand extends true ? Type : { [Key in keyof Type]: Normalize; }; /** * List of pairs that `Object.entries` returns. */ export type ObjectEntries = EntryPair[]; /** * Returns a tuple of two elements. If the second element includes `undefined`, * then it becomes optional in the tuple. * `OneOrTwoArgs<'foo', string>` = `[arg1: 'foo', arg2: string]`. * `OneOrTwoArgs<'foo', undefined | number>` = `[arg1: 'foo', arg2?: number]`. */ export type OneOrTwoArgs = IsIncludeUndefined extends true ? [arg1: Arg1, arg2?: Arg2] : [arg1: Arg1, arg2: Arg2]; /** * The property value will be optional if its default value * is included in the set of possible values. * `OptionalIfValueIncludeDefault<'foo', 1 | 2, 2>` = `{foo?: 1 | 2}`. * `OptionalIfValueIncludeDefault<'foo', 1 | 2, 3>` = `{foo: 1 | 2}`. * `OptionalIfValueIncludeDefault<'foo', {bar?: string}, {}>` = `{foo?: {bar?: string}}`. * `OptionalIfValueIncludeDefault<'foo', {bar: string}, {}>` = `{foo: {bar: string}}`. */ export type OptionalIfValueIncludeDefault = DefaultValue extends Value ? { [K in Key]?: Value; } : { [K in Key]: Value; }; /** * Takes a union, and returns the intersection of the elements of the union. * `UnionToIntersection<((x: string) => number) | ((x: number) => string)>` = * `((x: string) => number) & ((x: number) => string)`. */ export type UnionToIntersection = (Union extends unknown ? (arg: Union) => void : never) extends (arg: infer Intersection) => void ? Intersection : never; /** * If the type is a set, unwraps it and returns the set value type. * `UnwrapSet` = `number`. * `UnwrapSet>` = `string`. */ export type UnwrapSet = Type extends Set ? Value : Type; /** * Values of all properties of type `Type`. * `Values<{foo: 1, bar: 2}>` = `1 | 2`. * `Values<[1, 2], true>` = `1 | 2`. */ export type Values = WithArrays extends true ? Type extends readonly unknown[] ? Type[number] : Type[keyof Type] : Type[keyof Type]; /** * Returns a tuple of one element. If the element includes `undefined`, * then it becomes optional in the tuple. * `ZeroOrOneArg` = `[arg: string]`. * `ZeroOrOneArg` = `[arg?: number]`. */ export type ZeroOrOneArg = IsIncludeUndefined extends true ? [arg?: Arg] : [arg: Arg]; export {};