Reputation: 1415
I am kind of new to TypeScript
and I am trying to get rid of all any
types.
Problem:
Within the React
Component, I loop over an array of objects and extract a key/value
pair.
The components receives tags, tagKeys
props as follows:
tags: [{ name: "Some tag" }]
OR[{ platform: { name: "Some tag" } }];
tagKeys: ["name"]
ORtagKeys: ["platform", "name"]
If I run this script (below), I get this error in the console:
Element implicitly has an 'any' type because index expression is not of type 'number'
type Props = {
tags: any[];
tagKeys: string[];
};
const Tags: React.FC<Props> = ({ tags, tagKeys }: PropsWithChildren<Props>) => {
const renderTags = (): React.ReactNode => {
return tags.map(tag => {
let key = "";
// Loop through tagKeys in the tags array to extract the tag
for (let i = 0; i < tagKeys.length; i++) {
key = i === 0 ? tag[tagKeys[i]] : key[tagKeys[i]];
}
return <Tag key={`tag-${key}`} tag={key} />;
});
};
return <StyledTags>{renderTags()}</StyledTags>;
};
If I change the line inside the for loop to...
key = i === 0 ? tag[tagKeys[i] as any] : key[tagKeys[i] as any];
...the script runs but I want to get rid of the any
type.
Question:
Is there a way to set the type without specifying how the received props
array tags
will look?
I want to be able to pass arrays with different kinds of structure and extract a key/value pair.
Upvotes: 1
Views: 382
Reputation: 2522
There two issues to watch that we'll need to be clear about.
type Props = {
tags: any[]; // This is the answer to your direct question
tagKeys: string[];
};
TypeScript
is actually complaining about your index
.reactjs
uses the unique key
to render each <Tag>
.// TypeScript is actually warning you about this.
// Note that initially, `key` is of type `string` (implicitly or indirectly )
let key = "";
// Within your loop, you assign `key` to be of type `object`
key = i === 0 ? tag[tagKeys[i]] : key[tagKeys[i]];
// So the above line says that `key` can be `string` or `object`
// Thus TypeScript tells you that...
// implicitly your index (key) expression is of type any
To handle that TypeScript
error, update as follows:
let key: any = "";
Kindly make the necessary updates, and let me know how it goes for you.
Upvotes: 3
Reputation: 22340
key
can be either a string or an object during it's lifetime, so my first intuition would be to declare it as such:
let key: object | string = "";
But TS is not happy with that, so my second try would be:
type NestedObject = { [key: string]: NestedObject } | string
let key: NestedObject = '';
key = { platform: { name: 'dd' } }
key = key.platform.name
But TS is not happy with the last line either, so at this time I would just give up:
let key: any = '';
Upvotes: 1