Search code examples
typescriptenumsmapping

How can I define instance of arg with type Enum


I have a function which takes enum and returns value from one of two dictionaries.

Each dictionary has own enum as key. How can I refer to the correct dictionary, depending on the received enum?

Maybe I need to use another type?

enum firstSet {
  key1 = 'key-1',
  key2 = 'key-2',
  key3 = 'key-3',
}

enum secondSet {
  key1 = 'key-1',
  key2 = 'key-2',
  key3 = 'key-3',
}

type IDictionary1 ={
  [key in firstSet]: string
}

type IDictionary2 ={
  [key in secondSet]: string
}

const testDictionary1: IDictionary1 = {
  [firstSet.key1]: 'translate1',
  [firstSet.key2]: 'translate2',
  [firstSet.key3]: 'translate3'
}

const testDictionary2: IDictionary2 = {
  [secondSet.key1]: 'secondTranslate1',
  [secondSet.key2]: 'secondTranslate2',
  [secondSet.key3]: 'secondTranslate3'
}

const f = (key: firstSet | secondSet) => {
  ???
  const correctDictionary = `key from firstSet` ? testDictionary1 : testDictionary2
  ???

  return correctDictionary[key]
}

I can check each values in each enum, but it is really unproductive.


Solution

  • As rightly noted above - you need to think in terms of the code being compiled. Enum value compiles just to 'string', and impossible define original type. So you can based on original enum object. The best solution to this question is to create a factory that takes an enum object and returns functions, each using its own dictionary. Inside the factory, a mapping is made between the enum object and the dictionary. The question code only has two dictionaries, so I'm using the ternary operator for the logic example:

    const getF: {
        enumObj: typeof firstSet | typeof secondSet
    }: (key: firstSet | secondSet) => string = {
        const dictionary = enumObj === firstSet ? testDictionary1 : testDictionary2
        return (key: firstSet | secondSet) => {
            return dictionary[key]
        }
    }
    

    But for my task, I included the dictionary name as a prefix in the enum value.

    enum firstSet {
        key1 = 'testDictionary1:key-1',
        key2 = 'testDictionary1:key-2',
        key3 = 'testDictionary1:key-3',
    }
    

    And I parse them inside the function f: (firstSet | secondSet) => sring