Search code examples
javascriptreactjstypescript

How do I get the key of a value in a Typescript Record


Here's the code:

export type Period = 'dy' | 'wk' | 'mn' | 'qt' | 'yr';

const periods: Record<Period, string> = {
    dy: 'Day',
    wk: 'Week',
    mn: 'Month',
    qt: 'Quarter',
    yr: 'Year'
  };

When I try to do this:

const key = Object.keys(periods).find(key => periods[key] === 'Day');

I get an error of course, since periods[key] cannot guarantee that key is of the correct type. How should I really go about doing this? I thought of an enum but I can't do reverse lookups. All I'm trying to achieve is an input field that displays 'Day' but has a key of dy (etc.) and can set the state to the correct key and not the value when the user picks another value.


Solution

  • Object.keys returns string[] not Array<keyof T> (where T is the type of the value passed in). The reasons for this are outlined here.

    Since your object is probably not going to have unknown keys, you can use a type assertion:

    export type Period = 'dy' | 'wk' | 'mn' | 'qt' | 'yr';
    
    const periods: Record<Period, string> = {
      dy: 'Day',
      wk: 'Week',
      mn: 'Month',
      qt: 'Quarter',
      yr: 'Year'
    };
    
    const key = (Object.keys(periods) as Array<Period>).find(key => periods[key] === 'Day');
    

    Playground Link