Home > OS >  typescript object typing using an enum
typescript object typing using an enum

Time:08-24

I'm having a problem properly typing an object key to an enum. This is essentially what I have:

enum ItemTypes {
  WOOD,
  STONE
}

interface Item {
  owned: number,
  max: number
}

const stockpile: {[key in ItemTypes]: Item} = {}

I'm getting an error where stockpile is expecting the itemType enums to already exist within stockpile

Doing this works:

const stockpile: { [key: string]: Item } = {}

However, I would prefer it to be better typed as well as being able to export the enum to be used elsewhere. How would I go about this?

CodePudding user response:

THere is a big difference between stockpile and stockpile2

const stockpile: {
    [key in ItemTypes]: Item
} = {}

const stockpile2: {
    [key: string]: Item
} = {}

stockpile is and object with up front defined required keys 0 and 1. So, TS forbis you to use empty object when it expects two keys

stockpile2 is just indexed object. It means that there are no required keys/properties, however each key should be a string.

Summary

If you want to make required keys, you should use [key in ItemTypes] otherwise use [key: string]: Item

Hence, if you want to allow only keys from ItemTypes, use :

enum ItemTypes {
    WOOD,
    STONE
}

interface Item {
    owned: number,
    max: number
}

type Stockpile = Partial<Record<ItemTypes, Item>>

const stockpile: Stockpile = {} // ok

const stockpile2: Stockpile = {
    0: { owned: 1, max: 2 }
} // ok

const stockpile3: Stockpile = {
    0: { owned: 1, max: 2 },
    1: { owned: 1, max: 2 }
} // ok

Please keep in mind, that numerical enums are unsafe. Please see my article

Here you can find documentation about utility types: Partial, Record etc ...

  • Related