Issue
Let’s say I have this:
const color = {
red: null,
green: null,
blue: null
};
const newColor = ['red', 'green', 'blue'].filter(e => color[e]);
The error is in color[e]
near the bottom with:
Element implicitly has an ‘any’ type because expression of type
‘string’ can’t be used to index type ‘{ red: null; green: null; blue:
null; }’. No index signature with a parameter of type ‘string’ was
found on type ‘{ red: null; green: null; blue: null; }’.
I tried looking everywhere on TypeScript docs, but how the heck am I suppose to interface
this so it can accept color[e]
?
Solution
The problem you’re having is not that color
is the wrong type, but that TypeScript is inferring the type of ['red', 'green', 'blue']
to be string[]
. Often that type of inference is desirable, since (for all the compiler knows) you might want to push 'purple'
onto it. But in this case, you’d like the compiler to know that the only members are the three string literals 'red'
, 'green'
, and 'blue'
. That is, you need a type at least as specific as Array<'red'|'green'|'blue'>
.
Assuming you’re using TS3.4 or later, the easiest way to get this kind of type inference from the compiler is to use a const
assertion:
const constAssertionTest = ["red", "green", "blue"] as const;
// const constAssertionTest: readonly ["red", "green", "blue"];
The as const
causes the compiler to infer a tuple composed of exactly the three string literals in the array, in the exact order you’ve set. (It’s even a read-only tuple). That is good enough to fix your error:
const newColor = (['red', 'green', 'blue'] as const).filter(e => color[e]); // okay
All right, hope that helps. Good luck!
Answered By – jcalz
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0