I'm new to TypeScript and am trying to access the property of an object by a string. Here is a sandbox showing my problem: https://codesandbox.io/s/optimistic-mendel-f1zdg?file=/src/App.tsx
Code snippet (App.tsx: 17): newFlags[event.target.name] = event.target.value;
Error : Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ hidden: string; completed: string; }'.
I can make the error go away by adding an if statement like if(event.target.name === hidden || event.target.name === "completed")
but that solution seems really hard to scale. It seems great if I could use the <Flag>
type as a variable, but that seems to make TypeScript mad.
Is there a DRY solution to fixing this error?
This error makes sense since TS is a compiler, it can't know the exact runtime type of target.name
, if you are sure it's one of the Flag
keys, you should specify it:
// const flag = event.target.name as 'hidden' | 'completed';
const flag = event.target.name as keyof Flag
return { ...prevFlags, [flag]: event.target.value };
One approach is to declare the handler inline, and take the key from the outer scope instead of from the event target:
for (const [key, value] of Object.entries(flags)) {
flagSelectors.push(
<FlagFiltering
key={key}
name={key}
value={value}
handleChange={(e) => setFlags({
...flags,
[key]: e.target.value
})}
/>
);
}
I'd also recommend avoiding the mutator method .push
if something more appropriate exists, like .map
:
return (
<div className="App">{
Object.entries(flags).map(([key, value]) => (
<FlagFiltering
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.