I can't seem to figure out how to type the index signature properly here. I have an enum and need to iterate through it to put some JSX on the screen. I can guess what it's telling me but I can't solve it in my code. Both the Category[el]
statements are the problem.
export enum Category {
All = 'ALL',
Employee = 'EMPLOYEE',
Gear = 'GEAR',
Room = 'ROOM',
Other = 'OTHER',
}
My simplified function to render some JSX is:
const renderCategories = (): ReactElement | ReactElement[] => {
return Object.keys(Category).map(el => {
return (
<Option key={el} value={Category[el]}>
<span>{` (${someOtherData.filter((e) => e.type === Category[el].length})`}</span>
</Option>
);
});
};
TS tells me:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'typeof Category'.
No index signature with a parameter of type 'string' was found on type 'typeof Category'.
This use case is quite common as using Object.keys
which always infer each key as string
which is incompatible with key of like enum
or an object with a specific type.
But Typescript still allows us to cast this each key to a type which means we just simply cast back to type of above enum.
Here is the snippet reflecting the above explanation:
export enum Category {
All = 'ALL',
Employee = 'EMPLOYEE',
Gear = 'GEAR',
Room = 'ROOM',
Other = 'OTHER',
}
// A common type to detect the enum type
type EnumType = typeof Category;
type EnumKeyType = keyof EnumType;
// Then cast back to our desired type
someOtherData.filter((e) => e.type === Category[el as EnumKeyType].length) // cast `el as EnumKeyType`