Conditional type does not narrow union type
See original GitHub issueTypeScript Version: 3.2.2
Search Terms: conditional types, unions, narrowing
Code
interface A<T> {
value: T;
}
interface Specification {
[key: string]: Array<any> | Specification;
}
type Mapping<S extends Specification> = {
[key in keyof S]: S[key] extends Array<infer T> ? A<T> : Mapping<S[key]>
// Error ^^^^^^
// Type 'S[key]' does not satisfy the constraint 'Specification'.
// Type 'Specification[key]' is not assignable to type 'Specification'.
// Type 'any[] | Specification' is not assignable to type 'Specification'.
// Type 'any[]' is not assignable to type 'Specification'.
// Index signature is missing in type 'any[]'.
};
Expected behavior:
No error. “Leafs” of the Specification
tree, which have type Array<T>
(for some T
) should be mapped to A<T>
, while non-leaf properties should be recursively mapped.
Actual behavior:
In the right-hand side of the conditional type, S[key]
is not narrowed to Specification
, even if the complete type of S[key]
is Array<any> | Specification
and the Array<any>
case is catched in the left-hand side.
Playground Link: link
Related Issues: some similar issues related to conditional types, but I’m not sure whether this is a duplicate of any of them.
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (2 by maintainers)
Top Results From Across the Web
Conditional type that narrows a union - Stack Overflow
so if your code has arrived at a narrower type you have to widen by assertion (whether explicitly or through a helper function)....
Read more >Documentation - Narrowing - TypeScript
The “true” branch narrows x 's types which have either an optional or required property value , and the “false” branch narrows to...
Read more >Narrowing Types in TypeScript - Formidable Labs
To narrow a union type down to one, we'll need to consider each case. We can do this with good old-fashioned control flow...
Read more >The guide to conditional types in TypeScript - LogRocket Blog
TypeScript has support for conditional types, which might seem like ... Lastly, the distributive property doesn't hold if the union type is ...
Read more >Advanced TypeScript: The Power and Limitations of ... - Medium
Okay, but that's not very specific. We can do much better by introducing the infer keyword. The infer keyword can go inside of...
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
Conditional types do not produce substitution types for the false branch of the conditional (a.k.a do not narrow in the false branch).
There was an attempted fix here: #24821, however this was closed.
Alongside the narrowing mentioned here, Is it possible to add narrowing of union object types using
in
operator for conditional types?E.g-
It’d be nicer if this was possible instead-