Skip to content

Typing of Array.every and Array.some is too strict #30767

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MichaelTamm opened this issue Apr 5, 2019 · 3 comments
Closed

Typing of Array.every and Array.some is too strict #30767

MichaelTamm opened this issue Apr 5, 2019 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@MichaelTamm
Copy link
Contributor

TypeScript Version: 3.4.1

Search Terms:
Array, typing, some, every

Code

const a = [0, 1, 2];
console.log(a.every(x => x));  // ... false
console.log(a.some(x => x));  // ... true

Expected behavior:
Should compile without an error.

Actual behavior:
tsc complains with 2 errors TS2322: Type 'number' is not assignable to type 'boolean'.

Playground Link:
A link to a TypeScript Playground "Share" link which demonstrates this behavior

Related Issues:
none

In the spirit of "any valid JavaScript is also valid TypeScript" the code above should compile without errors.

The errors occur because of the type definitions of the Array methods every and some: The current decalration in lib.es5.d.ts states, that the first parameter callbackfn must return a boolean. This is (in my opinion) too strict, because the JavaScript spec says:

callbackfn should be a function that ... returns a value that is coercible to the Boolean value true or false.

Therefore the correct declaration should state, that callbackfn returns any:

interface Array<T> {
        ...
        every(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): boolean;
        ...
        some(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): boolean;
        ...
}

BTW, the Array method filter in lib.es5.d.ts is already declared like this:

        filter(callbackfn: (value: T, index: number, array: T[]) => any, thisArg?: any): T[];
@MartinJohns
Copy link
Contributor

MartinJohns commented Apr 5, 2019

Duplicate of #27496. Search terms used: is:issue array every some boolean

Changing the return type to any also means that this is legal: .same(() => {}). The inner function returns undefined and is compatible to any.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Apr 5, 2019
@MichaelTamm
Copy link
Contributor Author

Changing the return type to any also means that this is legal: .same(() => {}). The inner function returns undefined and is compatible to any.

Yes, indeed! .some(() => {}) is legal JavaScript (according to the spec) and should therefore not lead to an error.

I am aware, that the current typing of every and some might catch some bugs, but in practice it never did for me. But to work around the too strict typing I always have to use ... => !!(...) which is cumbersome.

Furthermore there is this asymmetry between the declaration of Array.filter and Array.every/Array.some in the current declarations.

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants