microsoft / microsoft/TypeScript

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

Offen
#60,070 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Awaiting More Feedback Suggestion
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.4k
Ø Merge
1 T. 19 Std.
Gemergte PRs (30 T.)
117

Beschreibung

🔎 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
}

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Reproduziere das Verhalten im verlinkten TypeScript Playground und konzentriere dich auf das generische mapValue-Beispiel und seinen Mapped Type mit umbenannten Schlüsseln. Vergleiche es mit der funktionierenden Variante key: 'foo'; das Ziel ist erreicht, wenn die generische Zuweisung akzeptiert wird und dabei die erwartete Beziehung zwischen Shape[K] und MappedShape[ShapeMap[K]] erhalten bleibt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
38/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.