镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

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

Description

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

  1. fatcerberus commented on Dec 10, 2019

    @fatcerberus

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

  2. 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);
  3. RyanCavanaugh commented on Dec 10, 2019

    @RyanCavanaugh
    Member

    Duplicate #31445

  4. 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!

  5. 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.

  6. locked as resolved and limited conversation to collaborators on Oct 21, 2025
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

      Issue actions