Search code examples
typescripttypescript-typings

Create a type from object keys dynamically


I have an icon-Map.json which is being created dynamically. Example:

const iconMap = {
    angleDoubleRight: 'angleDoubleRight.svg',
    angleRight: 'angleRight.svg',
    assets: 'assets.svg',
    barChart: 'barChart.svg',
    cancel: 'cancel.svg',
    chevronDown: 'chevronDown.svg',
    dotChart: 'dotChart.svg',
    dotMenu: 'dotMenu.svg',
    horizontalDots: 'horizontalDots.svg'
    ...

};
  • I can't create an interface manually from this object because I'm creating it dynamically so I can't use keyof.

  • Eventually, I want to create a type of iconMap's keys which I can use outside a component and it will strict my input to iconMap's keys only. (union or enum):

 type IconMapMember = 'angleDoubleRight' | 'angleRight' | 'assets' | ....

Solution

  • In your question you say you can't use keyof, but I'm not sure why. If you have an object whose keys are known at compile time (meaning that the iconMap variable is generated before you compile TypeScript code that uses it), you can use the typeof type query operator to get its type, and then use keyof on that:

    const iconMap = {
      angleDoubleRight: "angleDoubleRight.svg",
      angleRight: "angleRight.svg",
      assets: "assets.svg",
      barChart: "barChart.svg",
      cancel: "cancel.svg",
      chevronDown: "chevronDown.svg",
      dotChart: "dotChart.svg",
      dotMenu: "dotMenu.svg",
      horizontalDots: "horizontalDots.svg"
      //...
    };
    
    type IconMapMember = keyof typeof iconMap;
    // type IconMapMember = "angleDoubleRight" | "angleRight" | "assets" | "barChart" 
    // | "cancel" | "chevronDown" | "dotChart" | "dotMenu" | "horizontalDots" ...
    

    Link to code

    If you have some particular issue which prevents this solution from working, please update your question with more details about your build process. Hope this helps; good luck!