Home > Enterprise >  Second level key as types
Second level key as types

Time:05-10

I'm trying to define a type as a second level key for a given object. So for example, for object:

const myObj = {
  vegetabes: {
    legumes: ['chickpea', 'garbanzo', 'lentil'],
    tubers: ['potatoe', 'carrot']
  },
  meat: {
    farm: ['cow', 'goat', 'lamb'],
    wild: ['deer', 'bear']
  }
}

and function

const findRecipe = (firstLevelKey: keyof typeof myObj, secondLevelKey: ?????) => {
   const collection = myObj[firstLevelKey][secondLevelKey]
   ...
}

What type should I give secondLevelKey so that it is restricted to the keys inside the selected firstLevelKey? Ex: if I call findRecipe('vegetabes', ...) the only valid values for the second argument would be legumes and tubers. If that's not possible, it could be enough to restrict to any of the second level keys legumes, tubers, farm and wild. But the ideal would be to restrict based on the 1st key.

If anyone knows how to get this to work on a generic function <T>(firstLevelKey: keyof T, secondLevelKey: ?????) => {...} that would be nice too. But the important part would be what's described in the previous paragraph

CodePudding user response:

You probably would want to introduce a generic to ensure the keys are related correctly:

const findRecipe = <T extends keyof typeof myObj>(
  firstLevelKey: T,
  secondLevelKey: keyof typeof myObj[T]) => {
   const collection = myObj[firstLevelKey][secondLevelKey]
}

The fully generic version would be this:

function genericAccess<T, K extends keyof T>(
  instance: T,
  firstLevelKey: K,
  secondLevelKey: keyof T[K]
) {
   const item = instance[firstLevelKey][secondLevelKey];
}

Playground

  • Related