question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Consider re-ordering Array#reduce overloads in lib.d.ts

See original GitHub issue

Example code:

type UnaryFunction = (arg1) => any;
type BinaryFunction = (arg1, arg2) => any;

let binaryFuncs: BinaryFunction[] = [];
let unaryFunc = arg1 => {};
let reduced = binaryFuncs.reduce((prev, next) => prev, unaryFunc);

// ACTUAL:
let f: UnaryFunction = reduced;     // ERROR binary not assignable to unary

// EXPECTED:
let f: UnaryFunction = reduced;     // OK - both lhs and rhs really are unary

The call to Array#reduce in the above example definitely returns a unary function, but the type system erroneously infers the return type as a binary function.

This seems to be caused by the declaration order of the two overloads of Array#reduce in lib.d.ts. If the declaration order is reversed, the problem is solved.

The two overloaded declarations in lib.d.ts are as follows:

reduce(callbackfn: (previousValue: T, currentValue: T, currentIndex: number, array: T[]) => T, initialValue?: T): T;
reduce<U>(callbackfn: (previousValue: U, currentValue: T, currentIndex: number, array: T[]) => U, initialValue: U): U;

The first overload matches the example with T=BinaryFunction, since it satisfies the compiler’s assignability checks. So the second overload is never considered, even though it is a strictly better match, with T=BinaryFunction and U=UnaryFunction.

Would it be possible to swap the overload order for Array#reduce (and Array#reduceRight) in lib.d.ts to resolve this issue?

Issue Analytics

  • State:open
  • Created 8 years ago
  • Reactions:5
  • Comments:14 (8 by maintainers)

github_iconTop GitHub Comments

8reactions
johnnyreillycommented, Apr 4, 2016

Just stumbled on this - look forward to this being resolved! For anyone else wondering what to do in the interim just supply the type parameter. So to take @yortus example, this:

let arrayOfObjs: {}[] = [/*...*/];
let countOfProps = arrayOfObjs.reduce((sum, obj) => sum + Object.keys(obj).length, 0);

Becomes:

let arrayOfObjs: {}[] = [/*...*/];
let countOfProps = arrayOfObjs.reduce<number>((sum, obj) => sum + Object.keys(obj).length, 0);
2reactions
okmttdhrcommented, Sep 4, 2021

I re-created the PR https://github.com/microsoft/TypeScript/pull/37702 Can anybody check this?

Read more comments on GitHub >

github_iconTop Results From Across the Web

ramda/ramda - Gitter
@epeli strictly speaking an array in JS IS an object with keys that are numbers. There's no transformation you need to do really....
Read more >
Typed arrays and union types - javascript - Stack Overflow
I work with typed arrays a lot and a lot of my functions really should be able to work with any sort of...
Read more >
Array | typescript - v3.7.7
A function that accepts up to three arguments. The every method calls the callbackfn function for each element in the array until the...
Read more >
4001d68a6353c89b34e1108119... - FTP Directory Listing - IBM
/opt/ECX/virgo/repository/lib/libtcnative-1.so.0.2.6 /usr/bin/bsondump /usr/bin/mongo ... /opt/ECX/spp/node_modules/commander/typings/index.d.ts ...
Read more >
Essential TypeScript 4
Overloading Function Types ... standard function used with the array reduce method with an arrow ... C:/npm/node_modules/typescript/lib/lib.es2015.d.ts.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found