microsoft / microsoft/TypeScript
Confusing enum reverse string lookup behaviour in strict mode
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- Go
- Sterne
- 111k
- Forks
- 14.3k
- Ø Merge
- 2 T. 4 Std.
- Gemergte PRs (30 T.)
- 132
Beschreibung
Summary
Code below.
Typescript in --strict mode will reject enum reverse lookups using arbitrary strings with this very confusing error message:
Element implicitly has an 'any' type because index expression is not of type 'number'.
A workaround is to cast the string to a subset of all possible enum keys but that's impractical with large enums (or is there an easy way to say "any key of enum X" in TS?).
My real world use case: I have a react app with a <select> filter on various items, and a bunch of <option> values, all of which are part of an integer enum. I have to use the string representation in the dom, so the state of the filter has to be the string representation. When I check the item's enum value I already know it can only be one of those enum members.
This report is three-fold:
- Is this behaviour intended? There are cases where it can definitely catch a reverse lookup that can fail.
- If it is intended, then what is the correct way to declare that the lookup will always be valid?
let typeFilter: "FOO" | "BAR" = "FOO"is impractical and increases risk of errors. - Regardless of the above, the error message should be fixed. The element highlighted (
typeFilter) does not in fact have an "any" type, andType[typeFilter]will not beanyeither (in fact,Type[typeFilter] as Typedoes not fix it). An error such as "Reverse lookup on enum Type may fail because typeFilter is of type 'string'" is much clearer already.
Details
TypeScript Version: 3.2.2
Search Terms: enum reverse string lookup
Code
// test.ts
// Compile with `tsc --strict test.ts`
export enum Type {
FOO = 0,
BAR = 1,
}
const Test = () => {
// Change the following line to `let typeFilter: "FOO" | "BAR" = "FOO";` and it will work
let typeFilter = "FOO";
if (Type[typeFilter] != Type.FOO) {
return;
}
};
export default Test;
Actual behavior:
test.ts:9:11 - error TS7015: Element implicitly has an 'any' type because index expression is not of type 'number'.
9 if (Type[typeFilter] != Type.FOO) {
~~~~~~~~~~
Found 1 error.
Playground Link: Playground
Related Issues: Maybe #27297
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Reproduziere den Bericht aus dem bereitgestellten test.ts-Beispiel, indem du tsc --strict ausführst und die Diagnose bei Type[typeFilter] untersuchst. Lies den Typprüfpfad für die umgekehrte enum-Suche und das zugehörige Issue #27297, bevor du entscheidest, ob sich das Verhalten oder nur die Meldung ändern sollte; abgeschlossen bedeutet, dass das beabsichtigte Verhalten festgelegt und durch einen Regressionstest abgedeckt ist.
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
- 35/100