Get the key of an object by its value

January 22, 2023TypeScript

3 min read

Let's take a look at how we can get the key of a JavaScript object by its value. It's essentially a reverse lookup on the object in order to get the object key for a certain object value.

Getting a key by its value

Let's say we have a Podium object with a mapping of podium placement strings to numeric representations.

To find the Podium key that corresponds to a certain Podium value, we can loop over the keys of Podium and do an equality check on each key's value.

const Podium = {
  first: 1,
  second: 2,
  third: 3,
};

// TypeScript ERROR for `Podium[key]`
const key = Object.keys(Podium).find(key => Podium[key] === 3);
console.log(key);

The Podium[key] reference in the code above results in the following TypeScript error:

Element implicitly has an 'any' type because expression 
of type 'string' can't be used to index type 
'{ first: number; second: number; third: number; }'. No 
index signature with a parameter of type 'string' was found...

What does this error mean? It means that TypeScript is unable to index or reference the obejct Podium by using a key with a string value, such as "first". The reason for this is because we didn't provide TypeScript with the exact type structure of our Podium object.

We should tell TypeScript the exact properties and data types that make up Podium object.

Typing the object

const Podium: { [key: string]: number } = {
  first: 1,
  second: 2,
  third: 3,
};

const key = Object.keys(Podium).find(key => Podium[key] === 3);
console.log(key); // "third"

By defining Podium with the type { [key: string]: number }, the initial TypeScript error is gone. The key "third" for the lookup that uses the value of 3 is now printed to the console.

keyof typeof operators

Rather than providing an explicit type for Podium, another solution is to use the TypeScript keyof operator and the JavaScript typeof operator.

const Podium = {
  first: 1,
  second: 2,
  third: 3,
};

const key = Object.keys(Podium).find(key => Podium[key as keyof typeof Podium] === 3);
console.log(key); // "third"

The Podium[key] reference now becomes Podium[key as keyof typeof Podium]. The TypeScript error is resolved and the key "third" is printed to the console.

The JavaScript typeof operator retrieves the type of a variable or property.

console.log(typeof Podium); // object

The keyof operator receives an object type and produces a literal union of all the keys that make up that object. Since keyof must receive an object type, we had to provide it with typeof Podium to produce the valid keyof expression keyof typeof Podium.

Here's an example to demonstrate how keyof works.

type PodiumKeyType = keyof typeof Podium;
let runner: PodiumKeyType;
runner = "first";
runner = "second";
runner = "third";
// TypeScript ERROR
// Type '"fourth"' is not assignable to type '"first" | "second" | "third"'
runner = "fourth"; 

The type PodiumKeyType that we created above is the literal union type of "first" | "second" | "third". Thus, the runner variable that we declare to be of type PodiumKeyType can only be assigned the string values that make up that literal union type.

Conclusion

To get an object key by it's value in TypeScript, we can use either one of the approaches that we saw above.

  • Define the type of the object when we create it, or
  • Use the keyof and typeof operators when retrieving the object value by its key.