Type narrowing of generic types in control flow analysis
See original GitHub issueBug Report
Hello,
🔎 Search Terms
type narrowing, generic types, control flow analysis
🕗 Version & Regression Information
(see Playground) When trying to narrow generic types (unions), the control flow analysis is not aware of the narrowing. I also see that this PR: https://github.com/microsoft/TypeScript/pull/43183 was supposed to address this.
Please keep and fill in the line that best applies:
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about type narrowing
⏯ Playground Link
Playground link with relevant code
💻 Code
const INITIAL_STATE = {
1: 'test1',
2: 'test2',
};
type State = typeof INITIAL_STATE;
const stateReducer = <Type extends keyof State>(
state: State,
action: { type: Type; value: string } | { type: 'clear'; value: number },
) => {
if (action.type === 'clear') {
// action.value is "string | number", but should be "number"
return action.value;
}
return {
...state,
[action.type]: action.value,
};
};
stateReducer(INITIAL_STATE, { type: 'clear', value: 0 });
🙁 Actual behavior
action.value is "string | number"
🙂 Expected behavior
but should be “number”
Thanks in advance!
Issue Analytics
- State:
- Created a year ago
- Comments:5 (1 by maintainers)
Top Results From Across the Web
Documentation - Narrowing - TypeScript
This analysis of code based on reachability is called control flow analysis, and TypeScript uses this flow analysis to narrow types as it...
Read more >TypeScript - narrowing type from generic union type
Currently the compiler does not use control flow analysis to narrow generic type parameters or values of types dependent on generic type ...
Read more >TypeScript Generics and Type Guards - Explained by Example
Type guards are powerful for narrowing types, satisfying the TypeScript compiler's control flow process and guaranteeing runtime type-safety ...
Read more >توییتر \ Nick Nisi در توییتر: «TypeScript question: Is it possible to ...
testA using union type properly narrows the ternary. ... Improve narrowing of generic types in control flow analysis by ahejlsberg · Pull Request...
Read more >Generic Types | Flow
In Flow, most of the time when you pass one type into another you lose the original type. So that when you pass...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
{ type: Type; value: string } | { type: 'clear'; value: number }
is not a discriminated union so it may not be narrowed as the way you expected. To make it work, you have to distribute over the generic typeType
.It’s funny you say this because this was also my understanding for a long time. It’s only due to past comments by @RyanCavanaugh that I found out the rule is the discriminant can either be a unit type or a union of unit types (thus why
keyof State
works as a discriminant). So I certainly wouldn’t blame anyone who didn’t realize that.It’s interesting that that conditional type trick works. I would expect it to just defer since it’s distributive over a type parameter.