microsoft / microsoft/TypeScript
Extend type predicate inference to work with certain type variables
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.4k
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 117
Description
🔍 Search Terms
type predicate inference generic
✅ Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ Suggestion
When a function would normally serve as a type predicate for a discriminated union, but the exact cases being selected by the type predicate are dictated by a type variable, it'd be nice if the type predicate could still be inferred.
📃 Motivating Example
type Thing = A | B | C
type A = { kind: 'A', id: string, /* ... */ }
type B = { kind: 'B', id: string, /* ... */ }
type C = { kind: 'C', id: string, /* ... */ }
function filterByKind<T extends Thing['kind']>(things: Thing[], kind: T) {
return things.filter((it) => it.kind === kind);
}
// The below would ideally be typed as `A[]`, as the function passed to
// `filter` would have an inferred type predicate of `it is Thing & { kind: T }`
const x = filterByKind([], 'A');
const someKind = Math.random() < .5 ? 'A' : 'B';
const y = filterByKind([], someKind); // (A | B)[]
💻 Use Cases
I think this comes up somewhat rarely, and the workaround is to simply manually write out the generic type predicate, but, at my company, we did find cases like this when we looked at our type predicates as part of upgrading to TS 5.5
Contributor guide
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
No implementation files, tests, or entry points are named in the issue. Start by reproducing the motivating examples and investigate the existing type-predicate inference behavior. Done means the generic filterByKind examples infer A[] for 'A' and (A | B)[] for a union of kinds without changing runtime output.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100