简体   繁体   中英

How to use enum values to index an object?

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 .

https://www.typescriptlang.org/play/index.html?ssl=17&ssc=4&pln=1&pc=1#code/KYOwrgtgBAYg9nAJgZygbwFBSgIwE7ACGiUAvFAET5GIUA0WUERALmZc4S-RgL4YYAxnBDI28JMgCCePIQCe7ANoSUAOmrE6sBOs4sAugG4BLeQAdgUAMoALOOfMBLEAHMAMk7HtM2JQGtgRRcdSQMALigxPBdXE14TIRFvZHtHWM8xSLsHZzdMtnJfXAJiSIoARigAGzhCADMebH1ygCYanGQeBIFVaVkFNXq4PABRQkFbAAoppxZgCABKMgA+dEZhUThq4DVa1ynU3IyvFiU5hYNF+OugA

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM