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>>; export {};