🔎 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
}
🔎 Search Terms
typechecker, mapped object type, remapped keys, ts2322
🕗 Version & Regression Information
nightlyand every version down to 4.1.5 (first version supporting remapped keys)⏯ Playground Link
https://www.typescriptlang.org/play/?#code/C4TwDgpgBAygFgQ0lAvFA3lAZgexwLigGdgAnASwDsBzAbigCMFTDKBXAWwYlPoF9aAKFDJ4SCAFkkqDNjyEA5LhwAmBfSYsoCzWv5CR0KWEgATMcjSYA2gGkoVKAGsIIHFliJkCIp-HG7AF1AwgsIIKgBQUEsNkoAY2ByHEooDiQANQQAGzYIAB57CAAPYAhKU18XNw8wgD4ACkEoFudXQlsAGmbWoi8IUP7u1rSkM0JjMzDh1vSwQf8kboBKDB6W+JSSUZMIU1tXGTnrasChEc3KbYA3HLyZPvET1zP1nbNrObMDkECZW9yECEfCAA
💻 Code
🙁 Actual behavior
The error says
The second line is correct,
Shapeis different fromMappedShapesince they don't have any property names in common (which is the idea 🙂). That incompatibility is not relevant when it's the value inShape[K]that should be assignable toMappedShape[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]toMappedShape[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
fooas the key (Playground) it works correctly: