/* eslint-disable @typescript-eslint/no-unsafe-function-type */ /* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */ /* eslint-disable @typescript-eslint/no-explicit-any */ export type ToTuple = T extends any[] ? T : any[] /** * Union tow types, with optional excluded keys * @example `Spread` or `Spread` * @see https://github.com/microsoft/TypeScript/pull/13288#issuecomment-412230721 */ export type Spread = { [K in Exclude]: T1[K] } & { [K in Exclude]: T2[K] } /** * @example `type R = AllValues>` * @see https://stackoverflow.com/a/56416192 */ export type AllValues> = { [P in keyof T]: { key: P, value: T[P] } }[keyof T] /** * @example `type R = KeyFromValue<{uid: 'tbUserUid'}, 'tbUserUid'>` got `uid` * @ref https://stackoverflow.com/a/57726844 */ export type KeyFromValue = { [key in keyof T]: V extends T[key] ? key : never }[KnownKeys & keyof T] /** * Invert key/value of type/interface * @example `type R = Invert<{x: 'a', y: 'b'}>` got `{a: 'x', b: 'y'}` * @example `type R = Invert<{x: 'a', y: 'b', z: 'a'}>` got `{a: 'x' | 'z', b: 'y'}` * @see https://stackoverflow.com/a/57726844 */ export type Invert> = { [K in T[KnownKeys & (keyof T)]]: KeyFromValue } /** * @see https://github.com/microsoft/TypeScript/issues/27024#issuecomment-421529650 */ export type Equals = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? true : false /** * (Experimental) Equals two types which convert by FormatIntersect<> * ``` */ export type EqualsExt = Equals, FormatIntersect> export type OverwriteNeverToUnknown = { [fld in keyof T]: T[fld] extends never ? unknown : T[fld] } /** * (Experimental) Rewrite members of intersect type into one type deeply * * @example ```ts * {foo: number} & {bar: string} => {foo: number, bar: string} * ``` */ export type FormatIntersect = T extends Record ? T extends any[] | Function | Date ? T : { [K in keyof T]: deep extends true ? FormatIntersect : T[K] } : T /** * Retrieve keys * @see https://stackoverflow.com/a/51955852/2887218 */ export type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : symbol extends K ? never : K } extends { [_ in keyof T]: infer U } ? U : never /** * Retrieve types * @see https://stackoverflow.com/a/51955852/2887218 */ export type ValuesOf = T extends { [_ in keyof T]: infer U } ? U : never type IfAny = 0 extends (1 & T) ? Y : N /** * @link https://stackoverflow.com/a/55541672 */ export type OverwriteAnyToUnknown = IfAny /** * Restrict using either exclusively the keys of T or exclusively the keys of U. * * No unique keys of T can be used simultaneously with any unique keys of U. * * Example: * `const myVar: XOR` * * More: https://github.com/maninak/ts-xor */ export type XOR = (T | U) extends object ? (Without & U) | (Without & T) : T | U /** * Get the keys of T without any keys of U. */ export type Without = Partial, never>>