Skip to content

Loosen strictness of Array.prototype.includes() and Set.prototype.has() #60559

Closed

Description

🔍 Search Terms

Example:

const values = ['foo', 'bar', 'baz'] as const;
type ValidValue = (typeof values)[number];

function isValueValid(value: string): value is ValidValue {
    return values.includes(value);
                          // ^^ ts error: Argument of type 'string' is not assignable to parameter of type '"foo" | "bar" | "baz"'
}

This error seems counter intuitive as the entire point of includes is to check if value in foo.includes(value) is one of foo.
A Set and mySet.has(...) has the same issue.

playground

✅ Viability Checklist

⭐ Suggestion

I'd expect typescript to not show an error here.

💻 Use Cases

Now having to deal with the removal suppressImplicitAnyIndexErrors: true in typescript 5.6

Activity

  1. changed the title [-]Loosen strictness of `Array.prototype.includes()`[/-] [+]Loosen strictness of `Array.prototype.includes()` and `Set.prototype.has()`[/+] on Nov 22, 2024
  2. MartinJohns commented on Nov 22, 2024

    @MartinJohns
    Contributor

    Duplicate of #60073 and many many more. Your search terms seem excessive, no wonder you didn't find any of them. I suggest limiting your search terms to a few related word, often with the in:title modifier.

    IMO a type assertion is an appropriate workaround if this is intentional code.

  3. sod commented on Nov 22, 2024

    @sod
    Author

    sorry. Thank you for your time.

    I didn't see that improving this was already discussed and/or rejected.

  4. sod commented on Nov 22, 2024

    @sod
    Author

    reopen because it's not a duplicate of #60073.

    This ticket is not about making Array.prototype.includes() smarter. It's about not throwing an ts-error for 100% valid and deterministic usecase.

  5. MartinJohns commented on Nov 22, 2024

    @MartinJohns
    Contributor

    This is a duplicate of #60073, #26255 and many others, ending up with #14520.

    Your issue is the accepted type for includes(), same as the other.

    And I have no clue what "strict property access" (from your use case) is about, that's completely unrelated.

  6. sod commented on Nov 22, 2024

    @sod
    Author

    This is a duplicate of #60073, #26255 and many others, ending up with #14520.

    I aggree that this is a duplicate to #26255. A 6 year old, with 27 upvotes closed duplicate. But a duplicate non the less.

    Then I guess i have to write:

    + const inArray = (haystack: readonly any[], needle: string): boolean => haystack.includes(needle);
    + inArray(values, value)
    - values.includes(value)

    I hope nobody follows the recommendation on https://www.typescriptlang.org/tsconfig/#suppressImplicitAnyIndexErrors to use @ts-ignore, as that IMO is even worse.

    And I have no clue what "strict property access" (from your use case) is about, that's completely unrelated.

    Yes, strict property access made no sense. Removed that now from the description. This issue appeared when flicking "suppressImplicitAnyIndexErrors": true to false. A setting change that became mandatory with typescript@5.6.

    Sadly I can't show it in the playground, because "suppressImplicitAnyIndexErrors": true isn't available anymore, even if you select an older version.


    Fell free to close this issue.

  7. MartinJohns commented on Nov 22, 2024

    @MartinJohns
    Contributor

    Again, you can just use a type assertion, IMO the cleanest approach: values.includes(value as ValidValue)

  8. sod commented on Nov 22, 2024

    @sod
    Author

    values.includes(value as ValidValue)

    Indeed that works. Not sure why. I internalized that whenever I had to restort to typecasting, that my underlying types or generics are incorrect.

    Thank you.

  9. locked as resolved and limited conversation to collaborators on Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions