microsoft / microsoft/TypeScript

Narrow object property indexed by bracket notation when the key is a known literal type, regardless of where the key comes from

Offen
#61,176 1 Kommentar 11 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Domain: check: Control Flow Help Wanted Possible Improvement
Vorherrschende Sprache
Go
Sterne
111k
Forks
14.3k
Ø Merge
2 T. 4 Std.
Gemergte PRs (30 T.)
132

Beschreibung

🔍 Search Terms

type guard, narrowing, control flow analysis, property, index, known type, literal type, bracket notation

✅ Viability Checklist
⭐ Suggestion

This is a different re-opening or re-focusing of #10530, not the same as #56389, and was not fixed by #57847. The original motivating example for #10530 (treat obj["key"] like obj.key for narrowing) was fixed long ago, and more recently many of the remaining requests which had been added to #10530 were also fixed (narrowing for obj[key] when key is a variable whose literal type isn't known, for multiple uses of the same key). Those issues are closed. But it seems there are still some issues lumped in with #10530 which were not addressed, so here's the suggestion:

Please enable narrowing of object properties accessed via bracket notation based on the type of the key whenever the key's type is a known literal, even if multiple distinct variables or properties are used as keys. That is, if you have key1 and key2 and keyObj.prop and they are all of the literal type "foo" (or have been narrowed to that type), then treat obj[key1] and obj[key2] and obj[keyObj.prop] all as obj.foo for control flow purposes.

📃 Motivating Example

#51368 gives one, where the variable is a let variable annotated with a literal type or const asserted :

let k: "foo" = "foo";
// let k = "foo" as const; // <-- same behavior
const obj = { foo: Math.random() < 0.5 ? "abc" : undefined }
if (obj.foo) { obj[k].toUpperCase() } // error!
//             ~~~~~~ possibly undefined

Probably I'd say someone should use a const there instead of let.


There's also one from this Stack Overflow question, involving enum-like const-asserted objects:

const Enum = { FOO: "foo", BAR: "bar" } as const;
const obj = { [Enum.FOO]: Math.random() < 0.5 ? "abc" : undefined }
if (obj[Enum.FOO]) obj[Enum.FOO].toUpperCase() // ERROR!
//                 ~~~~~~~~~~~~~ possibly undefined

This one strikes me as quite unfortunate, since an actual enum works just fine here:

enum Enum { FOO = "foo", BAR = "bar" }
const obj = { [Enum.FOO]: Math.random() < 0.5 ? "abc" : undefined  }
if (obj[Enum.FOO]) obj[Enum.FOO].toUpperCase() // OKAY
💻 Use Cases
  1. What do you want to use this for?

See #10530 and various issues closed as duplicates for more use cases.

  1. Current approaches and workarounds:

If TS knows the literal key then you do too, so you could always just use it directly:

const Enum = { FOO: "foo", BAR: "bar" } as const;
const obj = { [Enum.FOO]: Math.random() < 0.5 ? "abc" : undefined }
if (obj.foo) obj.foo.toUpperCase() // OKAY

That's reasonable, but I think it would be nice if there weren't this caveat for enum-like objects where you can't actually use them as keys directly for narrowing purposes.

Playground link to code

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

Beginnen Sie mit dem verknüpften TypeScript Playground-Beispiel und vergleichen Sie das verbleibende Verhalten mit den Issues #10530, #56389 und #57847. Das gewünschte Ergebnis ist, dass Zugriffe in eckigen Klammern, deren Schlüssel denselben bekannten Literaltyp haben, wie Zugriffe auf Eigenschaften per Punktnotation eingeengt werden, einschließlich des let-Schlüssels und der enum-artigen const-Objektbeispiele; es werden keine Implementierungsdateien oder Tests genannt.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
typescript
Bereich
compilers
Issue-Typ
Feature
Schwierigkeit
5/5
Geschätzter Aufwand
Über eine Woche
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

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