I have this code:
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 the error:
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 am I supposed to interface
this so it can accept color[e]
?
You can declare colors
as any
to tell TypeScript to get off your back on this one (aka explicit any ):
const color : any = {
red: null,
green: null,
blue: null
};
But if possible, strong typing is preferable:
const color : { [key: string]: any } = {
red: null,
green: null,
blue: null
};
More information on indexing in TypeScript: Index Signatures
EDIT: In this answer to a similar question, the author suggest using a Map<,>
-- if that fits your use-case.
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!
I know it is an old question but I'm not satisfied by the other answers. Please avoid the as
keyword as much as possible !
Let's see why we encounter this error and what to do with it.
When you do not give a type to a const, Typescript infers its type based on the initial value . Knowing that, the error just says "hey, e
could be any string, even strings that are not part of the inferred type of your const". What if e
was equal to 'yellow'
that is not known in color
inferred type?
I can recommend you 3 ways to handle this:
Just give a type string
to the keys of your const, like this:
const color: {[key:string]:null} = {
red: null,
green: null,
blue: null
};
Hmmm... That works, but we can do better.
Tell Typescript compiler you are using the keys of the inferred type of the const with the keywords: keyof typeof
.
In the given example, that would be:
const colorKeys: (keyof typeof color)[] = ['red', 'green', 'blue'];
const newColor = colorKeys.filter((e) => color[e]);
Can you still make a little extra effort? See next point.
Create an interface (or whatever you need as a type) and give it to your const. Then, specify the type of the array of strings with the keyof
keyword:
interface Color {
red:number|null;
green:number|null;
blue:number|null;
}
const color: Color = {
red: null,
green: null,
blue: null
};
const colorKeys: (keyof Color)[] = ['red', 'green', 'blue'];
const newColor = colorKeys.filter((e) => color[e]);
Thanks for all the great answers. New to typescript and successfully fixed my first road block.
// in javascript world this is what I used to do.
let values1 = products.reduce((acc, product) => {
acc[product] = 1;
// ^ --> Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
// No index signature with a parameter of type 'string' was found on type '{}'. TS7053
return acc;
}, {})
// in typescript world I needed an extract type specification for 'acc'
let values2 = products.reduce((acc: { [key: string]: number}, product) => {
acc[product] = 1; //No more error
return acc;
}, {})
Here's another solution using Record
const color: Record<string, null> = {
red: null,
green: null,
blue: null
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.