Skip to content

3.5 regression: invalid type for index lookup using constrained generic #32017

Closed
@OliverJAsh

Description

@OliverJAsh

TypeScript Version: 3.5.2

Search Terms: generic constraint constrained index lookup function union

Code

type MyRecord = {
    foo: { foo: number };
    bar: { bar: number };
};

type Tag = keyof MyRecord;

type MyUnion = MyRecord[Tag];

declare const values: {
    foo: MyRecord['foo'];
    bar: MyRecord['bar'];
};

declare const fns: {
    foo: () => MyRecord['foo'];
    bar: () => MyRecord['bar'];
};

declare const predicates: {
    foo: (value: MyUnion) => value is MyRecord['foo'];
    bar: (value: MyUnion) => value is MyRecord['bar'];
};

<T extends Tag>(tag: T) => {
    // 1.
    {
        const value = values[tag];
        type ExpectedType = MyRecord[T];
        // Expected: no error
        // 3.4 and 3.5: works as expected
        const test: ExpectedType = value;
    }

    // 2.
    {
        declare const value: MyUnion;
        // Expected: error
        // 3.4: no error
        // 3.5: works as expected
        const desired: MyRecord[T] = value;
    }

    // 3.
    {
        const fn = fns[tag];

        type ExpectedType = () => MyRecord[T];
        // Expected: no error
        // 3.4: works as expected
        // 3.5: unexpected error
        const test: ExpectedType = fn;
    }

    // 4. (this is our real world use case)
    {
        declare const value: MyUnion;
        const predicate = predicates[tag];

        if (predicate(value)) {
            // Expected: no error
            // 3.4: works as error
            // 3.5: unexpected error
            const desired: MyRecord[T] = value;
        }
    }
};

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions