/** * Given a union of indexable types `T`, we derive an indexable type * containing all of the keys of each variant of `T`. If a key is * present in multiple variants of `T`, then the corresponding type in * `Pathable` will be the intersection of all types for that key. * * @example * type T1 = Pathable<{a: number} | {a: string; b: boolean}> * // {a: number | string; b: boolean} * * type T2 = Pathable<{a?: {b: string}} * // {a: {b: string} | undefined} * * type T3 = Pathable<{a: string} | number> * // {a: string} * * type T4 = Pathable<{a: number} | {a: string} | {b: boolean}> * // {a: number | string; b: boolean} * * This type lets us answer the questions: * - Given some object of type `T`, what keys might this object have? * - If this object did happen to have a particular key, what values * might that key have? */ type Pathable = { [K in AllKeys]: TypesForKey; }; type AllKeys = T extends infer I ? keyof I : never; type TypesForKey = T extends infer I ? K extends keyof I ? I[K] : never : never; type StrictlyRequired = { [K in keyof T]-?: NonNullable; }; /** * Given some `A` which is a key of at least one variant of `T`, derive * `T[A]` for the cases where `A` is present in `T`, and `T[A]` is not * null or undefined. */ type PathValue1> = StrictlyRequired>[A]; /** All possible options after successfully reaching `T[A]`. */ type Pathable1> = Pathable>; /** As `PathValue1`, but for `T[A][B]`. */ type PathValue2, B extends keyof Pathable1> = StrictlyRequired>[B]; /** As `Pathable1`, but for `T[A][B]`. */ type Pathable2, B extends keyof Pathable1> = Pathable>; /** As `PathValue1`, but for `T[A][B][C]`. */ type PathValue3, B extends keyof Pathable1, C extends keyof Pathable2> = StrictlyRequired>[C]; /** * Gets the value at `path` of `object`. If the resolved value is `null` or `undefined`, the `defaultValue` is returned in its place. * * @param object - The target object. * @param path - The path of the property to get. * @param defaultValue - The default value. * @signature R.pathOr(object, array, defaultValue) * @example * R.pathOr({x: 10}, ['y'], 2) // 2 * R.pathOr({y: 10}, ['y'], 2) // 10 * @dataFirst * @category Object */ declare function pathOr>(object: T, path: readonly [A], defaultValue: PathValue1): PathValue1; declare function pathOr, B extends keyof Pathable1>(object: T, path: readonly [A, B], defaultValue: PathValue2): PathValue2; declare function pathOr, B extends keyof Pathable1, C extends keyof Pathable2>(object: T, path: readonly [A, B, C], defaultValue: PathValue3): PathValue3; /** * Gets the value at `path` of `object`. If the resolved value is `undefined`, the `defaultValue` is returned in its place. * * @param path - The path of the property to get. * @param defaultValue - The default value. * @signature R.pathOr(array, defaultValue)(object) * @example * R.pipe({x: 10}, R.pathOr(['y'], 2)) // 2 * R.pipe({y: 10}, R.pathOr(['y'], 2)) // 10 * @dataLast * @category Object */ declare function pathOr>(path: readonly [A], defaultValue: PathValue1): (object: T) => PathValue1; declare function pathOr, B extends keyof Pathable1>(path: readonly [A, B], defaultValue: PathValue2): (object: T) => PathValue2; declare function pathOr, B extends keyof Pathable1, C extends keyof Pathable2>(path: readonly [A, B, C], defaultValue: PathValue3): (object: T) => PathValue3; export { pathOr };