Skip to content

Mapped types lose type information #45560

Open

Description

Bug Report

Eager mapped types result in the indexed access of an union created from all elements of a tuple resulting in the widest type in the tuple.

🔎 Search Terms

eager mapped types, array intersection filtering

🕗 Version & Regression Information

This bug exists in every version of TypeScript available on the playground with support for the necessary language features through nightly. In 3.8.3, both assignments to test fail.

  • This changed between versions 3.8.3 and 3.9.7

⏯ Playground Link

Playground link with relevant code

💻 Code

interface ListElement {
    condition: boolean;
    id: string;
}

const list = [
    { condition: true, id: "yes" },
    { condition: false, id: "no" },
] as const;

type CheckCondition<
    List extends readonly ListElement[],
    ID extends List[number]["id"],
    > = ({ id: ID } & List[number])["condition"]

type Mapped = {
    [ID in "yes"]: CheckCondition<typeof list, ID>
}["yes"]

type NotMapped = CheckCondition<typeof list, "yes">

declare const mapped: Mapped
declare const notMapped: NotMapped

let test: true = true
test = mapped // error, should pass
test = notMapped

🙁 Actual behavior

The type constructed using a mapped type loses specificity, becoming (typeof list)[number]["condition"], which in this case is true | false == boolean

🙂 Expected behavior

The mapped type should have no effect on the resulting type.

This is the result of a question on the TS discord.

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

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions