question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Confusing enum reverse string lookup behaviour in strict mode

See original GitHub issue

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:

  1. Is this behaviour intended? There are cases where it can definitely catch a reverse lookup that can fail.
  2. 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.
  3. Regardless of the above, the error message should be fixed. The element highlighted (typeFilter) does not in fact have an “any” type, and Type[typeFilter] will not be any either (in fact, Type[typeFilter] as Type does 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

Issue Analytics

  • State:open
  • Created 5 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

9reactions
jack-williamscommented, Dec 19, 2018

let typeFilter: keyof typeof Type = "FOO";

I think

0reactions
weswighamcommented, Dec 19, 2018

The error message is correct, but in the case of enums, could stand to be improved (since the index signature is implicit). Something like

Element implicitly has an 'any' type because index expression is not an enum key or `number`.
Read more comments on GitHub >

github_iconTop Results From Across the Web

Reverse-Mapping for String Enums - javascript - Stack Overflow
The cleanest way I found so far is to make a secondary map: let reverseMode = new Map<string, Mode>(); Object.keys ...
Read more >
Nim Manual - Nim Programming Language
The construct identifier"string literal" (without whitespace between the identifier and the opening quotation mark) is a generalized raw string literal. It is a ......
Read more >
Lua 5.1 Reference Manual
The library function type returns a string describing the type of a given value. 2.2.1 – Coercion. Lua provides automatic conversion between ...
Read more >
Build settings reference | Apple Developer Documentation
A detailed list of individual Xcode build settings that control or change the way a target is built.
Read more >
LLVM Language Reference Manual
Describes the behavior of an allocation function. The KIND string contains comma separated entries from the following options: “alloc”: the function returns a ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found