mattpocock / mattpocock/ts-reset
Improve type narrowing for `.includes`
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 8.6k
- Forks
- 146
- PR merge metrics
- No merged PRs in 30d
Description
Given the following code:
(["a", "b", "c"] as const).includes(SOME_VALUE as 'a' | 'b' | 'd' )
we get a Typeguard that SOME_VALUE is 'a' | 'b' | 'c' — but in this case we know more about: we know it is not 'c' so it would be great to not have 'c' show up in the result again. The typeguard should narrow to 'a' | 'b'
One naive way to implement it would be something like:
interface ReadonlyArray<T> {
includes<TSearch extends T | (TSReset.WidenLiteral<T> & {})>(
searchElement: TSearch,
fromIndex?: number,
): searchElement is T & TSearch;
}
Diff:
interface ReadonlyArray<T> {
- includes(
- searchElement: T | (TSReset.WidenLiteral<T> & {}),
+ includes<TSearch extends T | (TSReset.WidenLiteral<T> & {})>(
+ searchElement: TSearch,
fromIndex?: number,
- ): searchElement is T;
+ ): searchElement is T & TSearch;
}
Is there any reason this shouldn't be done? If not I'd be glad to open a PR.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the ReadonlyArray.includes signature shown in the issue and the project's existing TypeScript type tests or augmentation entry point. Verify how the proposed generic signature affects the example, especially the resulting type guard, and add coverage demonstrating that 'c' is excluded from the narrowed result.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- developer-experience
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100