This is the lodash codebase, a modern JavaScript utility library delivering modularity, performance, and extras built with ES modules and TypeScript support.
Your task is to add TypeScript generics and type guards to enforce numeric return types on all numeric aggregation functions (sum, sumBy, mean, meanBy, min, minBy, max, maxBy).
Requirements:
- Create a type guard function
isNumericthat validates if a value can be safely used in numeric operations - Add TypeScript generic constraints to ensure iteratee functions return number | undefined | null
- Enforce return type of
number(including NaN) on all aggregation functions, neverstring - Add overload signatures for both property shorthand ('propName') and callback function patterns
- Ensure type inference works correctly when using property shorthand with typed arrays
Type guard implementation:
- isNumeric(value: unknown): value is number
- Should return false for strings, objects, arrays, symbols
- Should return true for numbers (including NaN, Infinity)
Files to create:
- src/.internal/isNumeric.ts - the type guard function
- src/types/aggregation.ts - shared types and interfaces for aggregation functions
Files to modify:
- src/sumBy.ts - add generic constraints and overloads
- src/meanBy.ts - add generic constraints and overloads
- src/minBy.ts - add generic constraints and overloads
- src/maxBy.ts - add generic constraints and overloads
Example usage with proper type inference: interface Product { name: string; price: number } const products: Product[] = [{ name: 'A', price: 10 }, { name: 'B', price: 20 }] _.sumBy(products, 'price') // infers number return type _.sumBy(products, (p) => p.price) // infers number return type _.sumBy(products, 'name') // TypeScript error: 'name' is not a numeric property
Tests to add:
- Type guard correctly identifies numeric vs non-numeric values
- Generic constraints reject non-numeric property keys at compile time
- Return types are correctly inferred as number
Use no semicolons. Follow existing lodash codebase patterns and conventions.
Added a dedicated numeric type guard and shared aggregation types, then wired new overloads + numeric constraints into sumBy, meanBy, minBy, and maxBy so both property shorthand and callback iteratees enforce numeric-only results and always return number (including NaN). Also added a TypeScript type test covering the guard, numeric key constraints, and return type inference in test/types/aggregation.test.ts.
Files added/updated:
src/.internal/isNumeric.tsandsrc/types/aggregation.tsfor the guard + shared typessrc/sumBy.ts,src/meanBy.ts,src/minBy.ts,src/maxBy.tsfor overloads + constraintstest/types/aggregation.test.tsfor type-level coverage
Tests not run (not requested). If you want, I can add a TypeScript test runner or wire these into an existing workflow.
lodash % npm install
lodash % npm run build
> lodash@4.17.23 build
> npm run build:main && npm run build:fp
> lodash@4.17.23 build:main
> node lib/main/build-dist.js
> lodash@4.17.23 build:fp
> node lib/fp/build-dist.js
lodash % npm test
> lodash@4.17.23 pretest
> npm run build
> lodash@4.17.23 build
> npm run build:main && npm run build:fp
> lodash@4.17.23 build:main
> node lib/main/build-dist.js
> lodash@4.17.23 build:fp
> node lib/fp/build-dist.js
> lodash@4.17.23 test
> npm run test:main && npm run test:fp
> lodash@4.17.23 test:main
> node test/test
Running lodash tests.
test.js invoked with arguments: ["/usr/local/Cellar/node/25.2.1/bin/node","/Users/flavioespinoza/Cursor/lodash/test/test"]
----------------------------------------
PASS: 6800 FAIL: 0 TOTAL: 6800
Finished in 10429 milliseconds.
----------------------------------------
> lodash@4.17.23 test:fp
> node test/test-fp
Running lodash/fp tests.
----------------------------------------
PASS: 327 FAIL: 0 TOTAL: 327
Finished in 108 milliseconds.
----------------------------------------