How to easily make an object type that accepts only certain strings as keys in TypeScript?

May 13, 2022 - 4 min read

To easily make an object type that accepts only certain strings as its keys, you can use the Record utility type and pass the union type of strings that should be the keys as its first type argument and the value type as its second argument type in TypeScript.

TL;DR

// a string literal union type composed of
// `cats`, `dogs` and `tigers` string
type Animals = "cats" | "dogs" | "tigers";

// make an object type where the keys should be of
// `ObjectKeys` type and values should be of any `string` value type
type AnimalSounds = Record<Animals, string>;

// make an animals sounds object
const animalSounds: AnimalSounds = {
  cats: "meow",
  dogs: "bow",
  tigers: "roar",
  // ❌ Error.
  // Object literal may only specify known properties,
  // and 'lions' does not exist in type 'AnimalSounds'.
  lions: "rooooar",
};

For example, let's say we need to make an object type where the keys of the object should contain the strings like cats, dogs, or tigers and the values can be any string type value.

To do that, first let's create a string literal union type called Animals composed of cats, dogs, and tigers string like this,

// a string literal union type composed of
// `cats`, `dogs` and `tigers` string
type Animals = "cats" | "dogs" | "tigers";

Now let's make the object type where the keys should be of the Animals type and the values can be of any string type values. To do that, we can use the Record utility type and pass the ObjectKeys type as its first argument type and string as the second argument type.

It can be done like this,

// a string literal union type composed of
// `cats`, `dogs` and `tigers` string
type Animals = "cats" | "dogs" | "tigers";

// make an object type where the keys should be of
// `ObjectKeys` type and values should be of any `string` value type
type AnimalSounds = Record<Animals, string>;

Finally we can make an object and use the AnimalSounds type as its type like this,

// a string literal union type composed of
// `cats`, `dogs` and `tigers` string
type Animals = "cats" | "dogs" | "tigers";

// make an object type where the keys should be of
// `ObjectKeys` type and values should be of any `string` value type
type AnimalSounds = Record<Animals, string>;

// make an animals sounds object
const animalSounds: AnimalSounds = {
  cats: "meow",
  dogs: "bow",
  tigers: "roar",
};

Let's try to add another key called lions which is currently not present in the Animals type like this,

// a string literal union type composed of
// `cats`, `dogs` and `tigers` string
type Animals = "cats" | "dogs" | "tigers";

// make an object type where the keys should be of
// `ObjectKeys` type and values should be of any `string` value type
type AnimalSounds = Record<Animals, string>;

// make an animals sounds object
const animalSounds: AnimalSounds = {
  cats: "meow",
  dogs: "bow",
  tigers: "roar",
  // ❌ Error.
  // Object literal may only specify known properties,
  // and 'lions' does not exist in type 'AnimalSounds'.
  lions: "rooooar",
};

As you can see that as soon as we add the lions key the TypeScript compiler shows us an error saying that the Object literal may only specify known properties, and 'lions' does not exist in type 'AnimalSounds'. which tells us that we cannot add an unknown key type called lions.

We have successfully made an object type that accepts only certain strings as keys in TypeScript. Yay 🥳!

See the above code live in codesandbox.

That's all 😃!

Feel free to share if you found this useful 😃.