/** * 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] } & {}; /** * 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)[]; } /** * 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]; export const hasAtLeastTwo = (ts: T[]): ts is [T, T, ...T[]] => ts.length > 1; export function hasProperties( obj: T, ...keys: K[] ): obj is T & { [J in K]: unknown } { return !!obj && keys.every(key => obj.hasOwnProperty(key)); }