UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 15.1 kB
{"version":3,"file":"prop.cjs","names":["output: unknown"],"sources":["../src/prop.ts"],"sourcesContent":["import type { KeysOfUnion } from \"type-fest\";\nimport type { ArrayAt } from \"./internal/types/ArrayAt\";\n\n// Computes all possible keys of `T` at `Path` spread over unions, allowing\n// keys from any of the results, not just those **shared** by all of them.\ntype KeysDeep<T, Path extends readonly unknown[]> = KeysOfUnion<\n PropDeep<T, Path>\n>;\n\n// Recursively run `Prop` over `Path` to extract the deeply nested type.\ntype PropDeep<T, Path extends readonly unknown[]> = Path extends readonly [\n infer Key,\n ...infer Rest,\n]\n ? PropDeep<Prop<T, Key>, Rest>\n : // Keys is a fixed tuple so we know we reach here only when we've reached\n // the output object.\n T;\n\n// Expanding on the built-in `T[Key]` operator to support arrays and unions.\ntype Prop<T, Key> =\n // Distribute the union to support unions of keys.\n T extends unknown\n ? // In a distributed union some of the union members might not be keys of a\n // specific object within a union of objects, those cases don't contribute\n // to the output type.\n Key extends keyof T\n ? T extends readonly unknown[]\n ? ArrayAt<T, Key>\n : T[Key]\n : undefined\n : never;\n\n// Currying relies on us being able to differentiate between data-first and\n// data-last invocations at runtime, but because the function takes a variadic\n// array of keys we can't rely on it's shape or length to do that. Instead, we\n// can limit the types we accept for `data` so that looking at the first\n// parameter's type is enough to make the call. From a practical standpoint\n// this means we accept in any `object`, `null,` or `undefined`, and that we\n// don't accept `string`. All other types (`boolean` and `bigint`) don't\n// have properties, so are incompatible with our `key` parameters anyway.\ntype NonPropertyKey = object | null | undefined;\n\n/**\n * Gets the value of the given property from an object. Nested properties can\n * be accessed by providing a variadic array of keys that define the path from\n * the root to the desired property. Arrays can be accessed by using numeric\n * keys. Unions and optional properties are handled gracefully by returning\n * `undefined` early for any non-existing property on the path. Paths are\n * validated against the object type to provide stronger type safety, better\n * compile-time errors, and to enable autocompletion in IDEs.\n *\n * @param data - The object or array to access.\n * @param key - The key(s) for the property to extract.\n * @signature\n * R.prop(data, ...keys);\n * @example\n * R.prop({ foo: { bar: 'baz' } }, 'foo'); //=> { bar: 'baz' }\n * R.prop({ foo: { bar: 'baz' } }, 'foo', 'bar'); //=> 'baz'\n * R.prop([\"cat\", \"dog\"], 1); //=> 'dog'\n * @dataFirst\n * @category Object\n */\nexport function prop<T extends NonPropertyKey, Key extends KeysDeep<T, []>>(\n data: T,\n key: Key,\n): NoInfer<Prop<T, Key>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n>(data: T, key0: Key0, key1: Key1): NoInfer<PropDeep<T, [Key0, Key1]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n Key8 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>,\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n key8: Key8,\n): NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n Key8 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>,\n Key9 extends KeysDeep<\n T,\n [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8]\n >,\n AdditionalKeys extends readonly PropertyKey[] = [],\n>(\n data: T,\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n key8: Key8,\n key9: Key9,\n ...additionalKeys: AdditionalKeys\n): NoInfer<\n PropDeep<\n T,\n [\n Key0,\n Key1,\n Key2,\n Key3,\n Key4,\n Key5,\n Key6,\n Key7,\n Key8,\n Key9,\n ...AdditionalKeys,\n ]\n >\n>;\n\n/**\n * Gets the value of the given property from an object. Nested properties can\n * be accessed by providing a variadic array of keys that define the path from\n * the root to the desired property. Arrays can be accessed by using numeric\n * keys. Unions and optional properties are handled gracefully by returning\n * `undefined` early for any non-existing property on the path. Paths are\n * validated against the object type to provide stronger type safety, better\n * compile-time errors, and to enable autocompletion in IDEs.\n *\n * @param key - The key(s) for the property to extract.\n * @signature\n * R.prop(...keys)(data);\n * @example\n * R.pipe({ foo: { bar: 'baz' } }, R.prop('foo')); //=> { bar: 'baz' }\n * R.pipe({ foo: { bar: 'baz' } }, R.prop('foo', 'bar')); //=> 'baz'\n * R.pipe([\"cat\", \"dog\"], R.prop(1)); //=> 'dog'\n * @dataLast\n * @category Object\n */\nexport function prop<T extends NonPropertyKey, Key extends KeysOfUnion<T>>(\n key: Key,\n): (data: T) => NoInfer<Prop<T, Key>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n>(key0: Key0, key1: Key1): (data: T) => NoInfer<PropDeep<T, [Key0, Key1]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n): (data: T) => NoInfer<PropDeep<T, [Key0, Key1, Key2]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n): (data: T) => NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n): (data: T) => NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n): (data: T) => NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n): (\n data: T,\n) => NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n): (\n data: T,\n) => NoInfer<PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n Key8 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>,\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n key8: Key8,\n): (\n data: T,\n) => NoInfer<\n PropDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8]>\n>;\nexport function prop<\n T extends NonPropertyKey,\n Key0 extends KeysDeep<T, []>,\n Key1 extends KeysDeep<T, [Key0]>,\n Key2 extends KeysDeep<T, [Key0, Key1]>,\n Key3 extends KeysDeep<T, [Key0, Key1, Key2]>,\n Key4 extends KeysDeep<T, [Key0, Key1, Key2, Key3]>,\n Key5 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4]>,\n Key6 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5]>,\n Key7 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6]>,\n Key8 extends KeysDeep<T, [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7]>,\n Key9 extends KeysDeep<\n T,\n [Key0, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8]\n >,\n AdditionalKeys extends readonly PropertyKey[] = [],\n>(\n key0: Key0,\n key1: Key1,\n key2: Key2,\n key3: Key3,\n key4: Key4,\n key5: Key5,\n key6: Key6,\n key7: Key7,\n key8: Key8,\n key9: Key9,\n ...additionalKeys: AdditionalKeys\n): (\n data: T,\n) => NoInfer<\n PropDeep<\n T,\n [\n Key0,\n Key1,\n Key2,\n Key3,\n Key4,\n Key5,\n Key6,\n Key7,\n Key8,\n Key9,\n ...AdditionalKeys,\n ]\n >\n>;\n\nexport function prop<K extends PropertyKey>(\n key: K,\n): <T extends Partial<Record<K, unknown>>>(data: T) => T[K];\n\nexport function prop(\n maybeData: NonPropertyKey | PropertyKey,\n ...args: readonly PropertyKey[]\n): unknown {\n return typeof maybeData === \"string\" ||\n typeof maybeData === \"number\" ||\n typeof maybeData === \"symbol\"\n ? (data: NonPropertyKey) => propImplementation(data, maybeData, ...args)\n : propImplementation(maybeData, ...args);\n}\n\nfunction propImplementation(\n data: NonPropertyKey,\n ...keys: readonly PropertyKey[]\n): unknown {\n let output: unknown = data;\n for (const key of keys) {\n if (output === undefined || output === null) {\n return undefined;\n }\n // @ts-expect-error [ts7053] -- This is fine, the types are really dynamic\n // here and TypeScript doesn't have a chance to infer them correctly.\n output = output[key];\n }\n return output;\n}\n"],"mappings":"AAubA,SAAgB,EACd,EACA,GAAG,EACM,CACT,OAAO,OAAO,GAAc,UAC1B,OAAO,GAAc,UACrB,OAAO,GAAc,SAClB,GAAyB,EAAmB,EAAM,EAAW,GAAG,EAAK,CACtE,EAAmB,EAAW,GAAG,EAAK,CAG5C,SAAS,EACP,EACA,GAAG,EACM,CACT,IAAIA,EAAkB,EACtB,IAAK,IAAM,KAAO,EAAM,CACtB,GAAI,GAAmC,KACrC,OAIF,EAAS,EAAO,GAElB,OAAO"}