Skip to content
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

Array#includes argument type is too narrow #36352

Closed
aquark opened this issue Jan 22, 2020 · 4 comments
Closed

Array#includes argument type is too narrow #36352

aquark opened this issue Jan 22, 2020 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@aquark
Copy link

aquark commented Jan 22, 2020

TypeScript Version: my project uses 3.5.3 but I can see the issue is still present in the master branch.

Search Terms: Array includes

Code

const b: string = 'b'
['a' as const].includes(b)

Expected behavior:
It should compile. Specifically, the type definition for Array#includes should allow for any searchElement type:

interface Array<T> {
    /**
     * Determines whether an array includes a certain element, returning true or false as appropriate.
     * @param searchElement The element to search for.
     * @param fromIndex The position in this array at which to begin searching for searchElement.
     */
    includes(searchElement: unknown, fromIndex?: number): boolean;
}

It is type-safe to ask whether an array contains any value for the same reason it is type-safe to compare any two types with ===. The example above is a toy example but this pattern shows up all the time in real-world use, e.g. to check if a string is a member of a union of strings.

Actual behavior:
Argument of type 'string' is not assignable to parameter of type '"a"'

Related Issues: None found

@jcalz
Copy link
Contributor

jcalz commented Jan 22, 2020

Duplicate of #26255

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Jan 22, 2020
@aquark
Copy link
Author

aquark commented Jan 22, 2020

Seems like this keeps coming up because there are common idioms which cannot be expressed without unsafe casts. I hear the argument that TS should prevent stupid errors, at the same time it should also try to support idiomatic code naturally. I would argue that until bivariant argument types are supported, it would be better to give this a less restrictive type which supports all the standard use cases, rather than encourage casting. Compare Java's Collection#contains for example.

@jcalz
Copy link
Contributor

jcalz commented Jan 22, 2020

Relevant SO answer about this

@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