Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incomplete typecheck when assigning to a mapped object type with remapped keys #60070

Open
hampustagerud opened this issue Sep 26, 2024 · 0 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@hampustagerud
Copy link

🔎 Search Terms

typechecker, mapped object type, remapped keys, ts2322

🕗 Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about mapped types.
    • Tried on nightly and every version down to 4.1.5 (first version supporting remapped keys)

⏯ Playground Link

https://www.typescriptlang.org/play/?#code/C4TwDgpgBAygFgQ0lAvFA3lAZgexwLigGdgAnASwDsBzAbigCMFTDKBXAWwYlPoF9aAKFDJ4SCAFkkqDNjyEA5LhwAmBfSYsoCzWv5CR0KWEgATMcjSYA2gGkoVKAGsIIHFliJkCIp-HG7AF1AwgsIIKgBQUEsNkoAY2ByHEooDiQANQQAGzYIAB57CAAPYAhKU18XNw8wgD4ACkEoFudXQlsAGmbWoi8IUP7u1rSkM0JjMzDh1vSwQf8kboBKDB6W+JSSUZMIU1tXGTnrasChEc3KbYA3HLyZPvET1zP1nbNrObMDkECZW9yECEfCAA

💻 Code

type Shape = { foo: string; bar: number; };
type ShapeMap = { foo: 'foo2'; bar: 'bar2'; };
type MappedShape = { [K in keyof Shape as ShapeMap[K]]: Shape[K] };

function mapValue<K extends keyof Shape>(
    key: K,
    shape: Shape,
    mapped: MappedShape,
    map: ShapeMap,
) {
    const mappedKey = map[key];
    const value = shape[key];
    mapped[mappedKey] = value; // <-- Not allowed to assign `value` here
}

🙁 Actual behavior

The error says

Type 'Shape[K]' is not assignable to type 'MappedShape[ShapeMap[K]]'.
  Type 'Shape' is missing the following properties from type 'MappedShape': foo2, bar2

The second line is correct, Shape is different from MappedShape since they don't have any property names in common (which is the idea 🙂). That incompatibility is not relevant when it's the value in Shape[K] that should be assignable to MappedShape[ShapeMap[K]].

To an uninitiated eye it looks like the typechecking either ends too early or too late since it compares the wrong types when trying to do the assignment. That's just a guess that might be incorrect so take that with all the salt you want 👍

🙂 Expected behavior

Assigning Shape[K] to MappedShape[ShapeMap[K]] should be allowed since they are the same types when resolved.

Additional information about the issue

If changing the code to always take foo as the key (Playground) it works correctly:

type Shape = { foo: string; bar: number; };
type ShapeMap = { foo: 'foo2'; bar: 'bar2'; };
type MappedShape = { [K in keyof Shape as ShapeMap[K]]: Shape[K] };

function mapValue(
    key: 'foo',
    shape: Shape,
    mapped: MappedShape,
    map: ShapeMap,
) {
    const mappedKey = map[key];
    const value = shape[key];
    mapped[mappedKey] = value; // No type error
}
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature labels Sep 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants