Skip to content

TS2345 error with derivated types from a map of types #35613

Closed
@lgraziani2712

Description

@lgraziani2712

TypeScript Version: 3.7.2

Search Terms: ts2345 derivated type error

I really don't know how to describe this bug in short terms.

Code

enum A {
    a = 'a',
    b = 'b'
}

interface ObjA {
    prop1: string;
}
interface ObjB {
    prop2: number;
}

type PayloadMap = {
    [A.a]: ObjA;
    [A.b]: ObjB;
}

type Content<T extends A> = {
    type: T;
    payload: PayloadMap[T];
}

function processContent<T extends A>(content: Content<T>) {
    parserPayload[content.type](content.payload);
//                              ^=========== here is the error
}

const parserPayload: { [key in A]: (payload: PayloadMap[key]) => any } = {
//                                           ^============ because this is treated
//                                                         as an intersection
    a: payload => payload.prop1,
    b: payload => payload.prop2,
}

Expected behavior: To correctly know that PayloadMap[key] is in fact the same as PayloadMap[T] since key matches T.

Actual behavior:

Argument of type 'PayloadMap[T]' is not assignable to parameter of type 'ObjA & ObjB'.

Playground Link: https://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=30&pc=2#code/KYOwrgtgBAglDeAoKKoEMoF4oHI04BplUAjLXEnRAX0UQEsQAXYAJwDM0BjYKAeRIArOElRQADqwD24gIwAuKAGcmrRgHMA3DQbM2nHvyEAhBMRSSZAJkXgIJNttqImAT3G8ACmlcAbKWgAJgCyaOLkoqgA2jAAdGgAuooCwtpiMbEkSUaCxk50bh5QAMJSeswAPAAqUMAAHiwggUqwAHwR5lCFwIpVaajiPv5Bit5+ASFhUVUJ+YjsYCBcTPRlEtI8Skql5UzVtQ2gzW0AFFxljUyKO5fVrQCUZmKDrEpsY8OBUee7sd0JZwuoCYsUG4yC9zmPxUEjQr3eQwmingUCiAGtgK4oIxYNkTmDPqNEUFQuJ0ZiEo9MO00CAsdQOmI0IoCRMsO1WUFQdI5EQxCQWcTAuzYeDAtzrERqEA

Related Issues:

Activity

fatcerberus

fatcerberus commented on Dec 10, 2019

@fatcerberus

Indexed access produces intersection type => most likely caused by #30769.

RyanCavanaugh

RyanCavanaugh commented on Dec 10, 2019

@RyanCavanaugh
Member

TS doesn't know that this is OK to do. You could have written this, which would be seen equivalently:

function processContent<T extends A>(content1: Content<T>, content2: Content<T>) {
    parserPayload[content1.type](content2.payload);
}
declare const a: Content<A.a>, b: Content<A.b>;
// Causes a runtime error, but is an OK call
processContent(a, b);
RyanCavanaugh

RyanCavanaugh commented on Dec 10, 2019

@RyanCavanaugh
Member

Duplicate #31445

lgraziani2712

lgraziani2712 commented on Dec 10, 2019

@lgraziani2712
Author

TS doesn't know that this is OK to do. You could have written this, which would be seen equivalently:

BTW, isn't that a kind of bug that TS doesn't check? There are a lot of business logic bugs with correct typings that TS isn't able to catch and that's OK. Isn't the bug you're exemplifying one of that kind?

Thank you for your rapid response!

RyanCavanaugh

RyanCavanaugh commented on Dec 10, 2019

@RyanCavanaugh
Member

That's a type error, not a business logic error. You can construct examples that observe a string where a number is expected, for example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @fatcerberus@RyanCavanaugh@lgraziani2712

        Issue actions

          TS2345 error with derivated types from a map of types · Issue #35613 · microsoft/TypeScript