I have an object that uses enum
values as keys. I'd like to iterate those enum
values and use them to index the said object:
enum Foods {
bread = "bread",
meat = "meat",
}
type ShoppingList = {
[Foods.bread]: string;
[Foods.meat]: string;
};
const shoppingList: ShoppingList = {
bread: "1 loaf",
meat: "2 lbs",
};
Object.keys(Foods).forEach((item) => {
console.log(shoppingList[item]);
});
This does build with tsc
, but ts-node
and VS Code are both reporting:
error TS7053: Element implicitly has an 'any' type because expression of type
'string' can't be used to index type 'ShoppingList'. No index signature with
a parameter of type 'string' was found on type 'ShoppingList'.
17 console.log(shoppingList[item]);
~~~~~~~~~~~~~~~~~~
Understandable, because Object.keys
returns string[]
. However, you and I know that those strings will only ever be members of Foods
. And because ShoppingList
only uses Foods
as its keys, we should be able to use any member of Object.keys
to index shoppingList
.
This makes sense conceptually but how would I communicate this to TypeScript?
Edit : Foods
and ShoppingList
need to stick to those two values, ie no dynamic keys here.
You can't using only an enum
.
You could of course just use casting to tell TS what the type of item
will be:
console.log(shoppingList[item as Foods]);
But that would get tiresome to write every time you need to cast Foods
.
Another option would be to declare an array that is explicitly defined:
enum Foods {
bread = "bread",
meat = "meat",
}
const FoodsArray = [Foods.bread, Foods.meat];
// Optional: use [key in Foods] to consolidate type definition
type ShoppingList = {
[key in Foods]: string;
};
const shoppingList: ShoppingList = {
bread: "1 loaf",
meat: "2 lbs",
};
FoodsArray.forEach((item) => {
console.log(shoppingList[item]);
});
Is it a bit redundant to have to manually declare and update an array? Yes. But as far as I know there is no way to infer accurate types directly from an enum
.
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.