1

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, i.e. no dynamic keys here.

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.