UNPKG

remeda

Version:

A utility library for JavaScript and Typescript.

1 lines 4.84 kB
{"version":3,"file":"fromKeys.cjs","names":["purry","result: Partial<FromKeys<T, V>>"],"sources":["../src/fromKeys.ts"],"sourcesContent":["import type { Simplify } from \"type-fest\";\nimport type { BoundedPartial } from \"./internal/types/BoundedPartial\";\nimport type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport { purry } from \"./purry\";\n\n// Takes a union of literals and creates a union of records with the value V for\n// each key **separately**\n// @example ExactlyOneKey<\"cat\" | \"dog\", boolean> // { cat: boolean } | { dog: boolean }\ntype ExactlyOneKey<T, V> = T extends PropertyKey ? Record<T, V> : never;\n\ntype FromKeys<T extends IterableContainer, V> = T extends readonly []\n ? // eslint-disable-next-line @typescript-eslint/no-empty-object-type -- We want to return an empty object type here, but it's not trivial to build that in Typescript, other fixer suggestions like Record<PropertyKey, never> or Record<PropertyKey, unknown> both break our type tests so they don't do what we need here. Because the result is mutable this might be the correct type after all...\n {}\n : T extends readonly [infer Head, ...infer Rest]\n ? ExactlyOneKey<Head, V> & FromKeys<Rest, V>\n : T[number] extends PropertyKey\n ? BoundedPartial<Record<T[number], V>>\n : never;\n\n/**\n * Creates an object that maps each key in `data` to the result of `mapper` for\n * that key. Duplicate keys are overwritten, guaranteeing that `mapper` is run\n * for each item in `data`.\n *\n * There are several other functions that could be used to build an object from\n * an array:\n * * `indexBy` - Builds an object from an array of *values* and a mapper for keys.\n * * `pullObject` - Builds an object from an array of items with mappers for *both* keys and values.\n * * `fromEntries` - Builds an object from an array of key-value pairs.\n * Refer to the docs for more details.\n *\n * @param data - An array of keys of the output object. All items in the array\n * would be keys in the output array.\n * @param mapper - Takes a key and returns the value that would be associated\n * with that key.\n * @signature\n * R.fromKeys(data, mapper);\n * @example\n * R.fromKeys([\"cat\", \"dog\"], R.length()); // { cat: 3, dog: 3 } (typed as Partial<Record<\"cat\" | \"dog\", number>>)\n * R.fromKeys([1, 2], R.add(1)); // { 1: 2, 2: 3 } (typed as Partial<Record<1 | 2, number>>)\n * @dataFirst\n * @category Object\n */\nexport function fromKeys<T extends IterableContainer<PropertyKey>, V>(\n data: T,\n mapper: (item: T[number], index: number, data: T) => V,\n): Simplify<FromKeys<T, V>>;\n\n/**\n * Creates an object that maps each key in `data` to the result of `mapper` for\n * that key. Duplicate keys are overwritten, guaranteeing that `mapper` is run\n * for each item in `data`.\n *\n * There are several other functions that could be used to build an object from\n * an array:\n * * `indexBy` - Builds an object from an array of *values* and a mapper for keys.\n * * `pullObject` - Builds an object from an array of items with mappers for *both* keys and values.\n * * `fromEntries` - Builds an object from an array of key-value pairs.\n * Refer to the docs for more details.\n *\n * @param mapper - Takes a key and returns the value that would be associated\n * with that key.\n * @signature\n * R.fromKeys(mapper)(data);\n * @example\n * R.pipe([\"cat\", \"dog\"], R.fromKeys(R.length())); // { cat: 3, dog: 3 } (typed as Partial<Record<\"cat\" | \"dog\", number>>)\n * R.pipe([1, 2], R.fromKeys(R.add(1))); // { 1: 2, 2: 3 } (typed as Partial<Record<1 | 2, number>>)\n * @dataLast\n * @category Object\n */\nexport function fromKeys<T extends IterableContainer<PropertyKey>, V>(\n mapper: (item: T[number], index: number, data: T) => V,\n): (data: T) => Simplify<FromKeys<T, V>>;\n\nexport function fromKeys(...args: ReadonlyArray<unknown>): unknown {\n return purry(fromKeysImplementation, args);\n}\n\nfunction fromKeysImplementation<T extends IterableContainer<PropertyKey>, V>(\n data: T,\n mapper: (item: T[number], index: number, data: T) => V,\n): FromKeys<T, V> {\n const result: Partial<FromKeys<T, V>> = {};\n\n for (const [index, key] of data.entries()) {\n // @ts-expect-error [ts7053] - There's no easy way to make Typescript aware that the items in T would be keys in the output object because it's type is built recursively and the \"being an item of an array\" property of a type is not \"carried over\" in the recursive type definition.\n result[key] = mapper(key, index, data);\n }\n\n return result as FromKeys<T, V>;\n}\n"],"mappings":"wCA0EA,SAAgB,EAAS,GAAG,EAAuC,CACjE,OAAOA,EAAAA,EAAM,EAAwB,EAAK,CAG5C,SAAS,EACP,EACA,EACgB,CAChB,IAAMC,EAAkC,EAAE,CAE1C,IAAK,GAAM,CAAC,EAAO,KAAQ,EAAK,SAAS,CAEvC,EAAO,GAAO,EAAO,EAAK,EAAO,EAAK,CAGxC,OAAO"}