0

I want to create an interface with generic keys limited by, say an enum, ensuring that the interface only accept certain keys and values.

I imagine doing something like this

interface IFruit<TargetKey extends string, TargetValue> {
  [key: TargetKey]: TargetValue;
}

Where the interface could be defined using the following:

enum Keys {
  APPLES = 'APPLES',
  ORANGES = 'ORANGES',
}

enum Values {
  GREEN = 'GREEN',
  BLUE = 'BLUE',
  ORANGE = 'ORANGE',
}

const test: IFruit<Keys, Values> = {
  Keys.APPLES: Values.GREEN,
  'POTATOES': 'BLUE', // Should give an error, as key is not in Keys enum
}

I'm not sure if this is possible to even achieve. So far I get an index signature error An index signature parameter type must be 'string' or 'number'. Is there a way to get this to work?

Joachim
  • 567
  • 1
  • 7
  • 20
  • 1
    Yes, you're looking for the built-in mapped type `Record`. I'm almost positive this is a duplicate question (looking, looking) – jcalz May 14 '19 at 15:05
  • 1
    Also the computed property in `test` should be in brackets: `[Keys.APPLIES]: Values.GREEN` – Aaron Beall May 14 '19 at 15:08
  • Relevant: [What is the Record type in typescript?](https://stackoverflow.com/questions/51936369/what-is-the-record-type-in-typescript) – jcalz May 14 '19 at 15:08
  • Possible duplicate of [Using an enum as a dictionary key](https://stackoverflow.com/questions/54542318/using-an-enum-as-a-dictionary-key) – jcalz May 14 '19 at 15:13
  • It's almost the same at least. The difference is that I want to do with an interface and not a type, don't know if it really matters though... – Joachim May 14 '19 at 15:21
  • You can't have a mapped type as an interface, although if you have a concrete mapped type (meaning all its keys and properties are statically known and do not have an unresolved generic type parameter in it) you can extend it with an interface. That is, `interface IFruit extends Record {}` is fine as long as `Keys` and `Values` are concrete types like you have them – jcalz May 14 '19 at 15:26

0 Answers0