-
Couldn't load subscription status.
- Fork 13.1k
Description
TypeScript 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.