import * as React from 'react'; export * from './enumerable'; // (A - keys of B) // In set theory, this would be the set complement A ∖ B (https://en.wikipedia.org/wiki/Complement_(set_theory)#Relative_complement) // Example: // type A = {a: string, b: number, c: boolean} // type B = {b: number} // type result = Omit = {a: string, c: boolean} export type Omit = Pick>; /** * Get PropTypes of a component. * @example * const OtherComponent: React.FC<{ foo: string }> = () =>
{foo}
* type MyComponentProps = PropTypes & { bar: string } // {foo: string, bar: string} */ export type PropTypes = C extends React.ComponentType ? P : never; /** * ValueOf: similar to keyof, but picks a value. * * @example * type Person = { * name: string, * phone: number | null * } * * type PhoneType = ValueOf; // string | number | null */ export type ValueOf = T[keyof T]; /** * Arguments: Get type of arguments of a function. * @example * type Fn = (foo: string, bar: number) => void * type FnArguments = Arguments // [string, number] */ export type Arguments = F extends (...args: infer A) => any ? A : never; /** * Get type of array element * * @example * const Names = ["Robert", "Ollie", "John", "Cina", "Millie"] // typeof Names === string[] * type Name = ValueOfArray // string * * @example * // typeof readonlyNames === readonly ["Robert", "Ollie", "John", "Cina", "Millie"] * const nameTuple = ["Robert", "Ollie", "John", "Cina", "Millie"] as const * // Name === "Robert" | "Ollie" | "John" | "Cina" | "Millie" * type Name = ValueOfReadonlyArray */ export type ValueOfArray | ReadonlyArray> = T extends Array ? U : T extends ReadonlyArray ? RO : never; /** * Overwrite certain keys with new types. * * @example * type A = {a: string, b?: string} * type result = Overwrite = {a: string, b: string} * (Note that b is no longer optional) */ export type Overwrite = { [P in Exclude]: T1[P]; } & T2; /** * Converts union to intersection. * * @example * type A = "hello" | 5 * type IntersectionA = UnionToIntersection = "hello" & 5 */ export type UnionToIntersection = ( U extends any ? (k: U) => void : never ) extends (k: infer I) => void ? I : never; /** * Doing keyof UnionOfObjects in TypeScript will give you intersection of keys. For example: * type UnionOfObjects = {a: string, b: number} | {a: string} * type Keys = keyof UnionOfObjects // "a"[] * * Sometimes, you might want all possible keys, in other words, you want union of keys. You can use this type for it. * * @example * type UnionOfObjects = {a: string, b: number } | {a: string} * type AllKeys = KeyOfUnion // "a" | "b" */ export type KeyOfUnion = keyof UnionToIntersection; /** * Converts readonly array to non-readonly array. * * @example * const ReadonlyArray = [5, 4] as const; * * type NonReadonlyArray = NonReadonly */ export type NonReadonly> = T extends ReadonlyArray< infer X > ? X[] : never; /** * Remove types from T that are assignable to U */ export type Diff = T extends U ? never : T; /** * Remove types from T that are not assignable to U */ export type Filter = T extends U ? T : never; /** * Represents Some value, or None */ export type Option = T | undefined; /** * Given a tuple, get the type of the head of the tuple */ export type Head = T extends [any, ...any[]] ? T[0] : never; /** * Given a tuple, return a new tuple without the head */ export type Tail = ((...args: T) => any) extends ( arg: any, ...args: infer TT ) => any ? TT : []; /** * Append T to R where R is a tuple */ export type Prepend = ((t: T, ...rest: R) => any) extends ( ...tt: infer TT ) => any ? TT : never; /** * Reverses the given tuple type. */ export type Reverse = { return: Result; recurse: Reverse, Prepend, Result>>; }[Tuple extends [] ? 'return' : 'recurse']; /** * Force TS to load a type that has not been computed * (to resolve composed types that TS hasn't resolved). * https://pirix-gh.github.io/ts-toolbelt/modules/_any_compute_.html * * @example * // becomes {foo: string, baz: boolean} * type Foo = Compute<{bar: string} & {baz: boolean}> */ export type Compute = A extends Function ? A : { [K in keyof A]: A[K] } & {}; /** * Same as Partial, but recursively. * * @example * type A = { * foo: { * bar: string * } * } * * type B = PartialDeep * // Becomes { foo?: {bar?: string | undefined} | undefined } */ export type PartialDeep = T extends object ? { [K in keyof T]?: PartialDeep | undefined } : T; /** * Selectively apply Partial to certain properties. * * @example * type T = { * foo: string; * bar: string; * baz?: string | undefined; * } * * type OptionalBar = PartialKeys // { foo: string; bar?: string | undefined; baz?: string | undefined; } */ export type PartialKeys = Omit & { [P in K]?: T[P]; }; /** * Selectively apply Required to certain properties. * * @example * type T = { * foo: string; * bar?: string | undefined; * baz?: string | undefined; * } * * type RequiredBar = RequiredKeys // { foo: string; bar: string; baz?: string | undefined; } */ export type RequiredKeys = Omit & { [P in K]-?: T[P]; }; /** * Selectively apply Readonly to certain properties. * * @example * type T = { * foo: string; * bar: string; * readonly baz: string; * } * * type ReadonlyBar = ReadonlyKeys // { foo: string; readonly bar: string; readonly baz: string; } */ export type ReadonlyKeys = Omit & { readonly [P in K]: T[P]; }; /** * Generates the typings for usage with Object.keys * * @example * const Locations = { "Cina": "Austin", "John": "Austin", "Kevin": "Austin", "Nicky": "San Francisco", "Robert": "San Francisco" } * const KeysFromLocations = objectKeys(Locations) */ export function objectKeys(t: T) { return Object.keys(t) as (keyof T)[]; } /* * Get a type of awaited Promise value. * * @example * type StringPromise = Promise * * type Value = PromiseType // string */ export type PromiseType

= P extends Promise ? T : never; /** * Should be used in the `default:` case of a switch. * Will cause a compilation-time type error if the switch is not exhaustive. * See https://www.typescriptlang.org/docs/handbook/advanced-types.html * * @param x * @param returnValue If provided, doesn't throw at runtime, but returns this value. * * @example * type Type = "error" | "success" | "info" | "warning" * * const getIcon = (type: Type) => { * switch (type) { * case 'success': * return 'ok'; * case 'error': * return 'sad'; * case 'info': * return 'info-sign'; * default: * return assertNever(type); // Shows error, because 'warning' is not handled. * } * }; */ export const assertNever = (x: never, returnValue?: any): never => { if (returnValue !== undefined) { throw new Error('Unexpected object: ' + x); } else { return returnValue as never; } }; /** * Returns keys in a type T whose values matching type V. * * e.g. KeysOfType<{ foo: string; bar: number; baz: string }, string> -> "foo" | "baz" */ export type KeysOfType = { [K in keyof T]-?: T[K] extends V ? K : never; }[keyof T];