remeda
Version:
A utility library for JavaScript and Typescript.
1 lines • 3.2 kB
Source Map (JSON)
{"version":3,"file":"product.cjs","names":["purry"],"sources":["../src/product.ts"],"sourcesContent":["import type { IterableContainer } from \"./internal/types/IterableContainer\";\nimport { purry } from \"./purry\";\n\ntype Product<T extends IterableContainer<bigint> | IterableContainer<number>> =\n // Empty arrays would always result in a product of (a non-bigint) 1\n T extends readonly []\n ? 1\n : // Non-empty bigint arrays will always result in a bigint product.\n T extends readonly [bigint, ...ReadonlyArray<unknown>]\n ? bigint\n : // But an empty bigint array would result in a non-bigint 1.\n T[number] extends bigint\n ? bigint | 1\n : // Non-bigint arrays are always handled correctly.\n number;\n\n/**\n * Compute the product of the numbers in the array, or return 1 for an empty\n * array.\n *\n * Works for both `number` and `bigint` arrays, but not arrays that contain both\n * types.\n *\n * IMPORTANT: The result for empty arrays would be 1 (`number`) regardless of\n * the type of the array; to avoid adding this to the return type for cases\n * where the array is known to be non-empty you can use `hasAtLeast` or\n * `isEmpty` to guard against this case.\n *\n * @param data - The array of numbers.\n * @signature\n * R.product(data);\n * @example\n * R.product([1, 2, 3]); // => 6\n * R.product([1n, 2n, 3n]); // => 6n\n * R.product([]); // => 1\n * @dataFirst\n * @category Number\n */\nexport function product<\n T extends IterableContainer<bigint> | IterableContainer<number>,\n>(data: T): Product<T>;\n\n/**\n * Compute the product of the numbers in the array, or return 1 for an empty\n * array.\n *\n * Works for both `number` and `bigint` arrays, but not arrays that contain both\n * types.\n *\n * IMPORTANT: The result for empty arrays would be 1 (`number`) regardless of\n * the type of the array; to avoid adding this to the return type for cases\n * where the array is known to be non-empty you can use `hasAtLeast` or\n * `isEmpty` to guard against this case.\n *\n * @signature\n * R.product()(data);\n * @example\n * R.pipe([1, 2, 3], R.product()); // => 6\n * R.pipe([1n, 2n, 3n], R.product()); // => 6n\n * R.pipe([], R.product()); // => 1\n * @dataLast\n * @category Number\n */\nexport function product(): <\n T extends IterableContainer<bigint> | IterableContainer<number>,\n>(\n data: T,\n) => Product<T>;\n\nexport function product(...args: ReadonlyArray<unknown>): unknown {\n return purry(productImplementation, args);\n}\n\nfunction productImplementation<\n T extends IterableContainer<bigint> | IterableContainer<number>,\n>(data: T): T[number] {\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers -- The rule differentiates 1 and 1n :(\n let out = typeof data[0] === \"bigint\" ? 1n : 1;\n for (const value of data) {\n // @ts-expect-error [ts2365] -- Typescript can't infer that all elements will be a number of the same type.\n out *= value;\n }\n return out;\n}\n"],"mappings":"wCAqEA,SAAgB,EAAQ,GAAG,EAAuC,CAChE,OAAOA,EAAAA,EAAM,EAAuB,EAAK,CAG3C,SAAS,EAEP,EAAoB,CAEpB,IAAI,EAAM,OAAO,EAAK,IAAO,SAAW,GAAK,EAC7C,IAAK,IAAM,KAAS,EAElB,GAAO,EAET,OAAO"}