Skip to content

Conditional type does not narrow union type #29188

Open
@lodo1995

Description

@lodo1995

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDomain: Conditional TypesThe issue relates to conditional types

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions