DEV Community

Cover image for Type Operators (keyof and typeof) in TypeScript
Tomohiro Yoshida
Tomohiro Yoshida

Posted on

Type Operators (keyof and typeof) in TypeScript

Have you ever heard typeof operator?
I guess 99% of readers will say "yes".
However, do you really understand the difference of typeof between in TypeScript and JavaScript?
If you are not confident, no worries! This article is for you!
I am going to explain how to use Type Operators, keyof and typeof, in this article.

Type Operators

keyof operator

You may sometimes be tired of writing types. For example, here is an example:

const createPerson = (id: number, name: string, age: number) => {
  return {
    id,
    name,
    age
  };
};

interface Person {
  id: number;
  name: string;
  age: number;
}

const showPersonsProperty = (person: Person, key: "id" | "name" | "age") => {
  console.log("This person's " + key + " is " + person[key] + ".")
};

const person1 = createPerson(1234, "John", 20);

showPersonsProperty(person1, "name");
// [LOG]: "This person's name is John"

showPersonsProperty(person1, "age");
// [LOG]: "This person's age is 20."
Enter fullscreen mode Exit fullscreen mode

The above code is functional. But how did you feel about this?

Actually, we can make this code more concise by utilizing type operators!

We (and TypeScript's type checker) already know the possible argument to be passed to the "key" parameter when defining the Person interface.

If so, why don't we use this Person interface to get its keys?
Let me show the updated code.

const createPerson = (id: number, name: string, age: number) => {
  return {
    id,
    name,
    age
  };
};

interface Person {
  id: number;
  name: string;
  age: number;
}

const showPersonsProperty = (person: Person, key: keyof Person) => {
  console.log("This person's " + key + " is " + person[key] + ".");
};

const person1 = createPerson(1234, "John", 20);

showPersonsProperty(person1, "name");
// [LOG]: "This person's name is John"

showPersonsProperty(person1, "age");
// [LOG]: "This person's age is 20."
Enter fullscreen mode Exit fullscreen mode

In this updated code, we could refer to the keys of the Person interface instead of giving union type ("id" | "name" | "age") to the key parameter.
The keyof operator generates a union type from keys of Object Type (Interface). In the former example codes, "id" | "name" | "age" and keyof Person have the same meaning.
This technique will help your life when an object has tons of properties!

typeof operator

Next, what if a person object is declared manually, like the below code?

const person1 = {
  id: 4321,
  name: "Mike",
  age: 35
};

interface Person {
  id: number;
  name: string;
  age: number;
}

const showPersonsProperty = (person: Person, key: keyof Person) => {
  console.log("This person's " + key + " is " + person[key] + ".");
};

showPersonsProperty(person1, "name");
// [LOG]: "This person's name is Mike."

showPersonsProperty(person1, "age");
// [LOG]: "This person's age is 35."
Enter fullscreen mode Exit fullscreen mode

Hmm... This code works okay. But we can write simpler code by utilizing typeof operator.
Here is an example.

const person1 = {
  id: 4321,
  name: "Mike",
  age: 35
};

const showPersonsProperty = (person: typeof person1, key: keyof typeof person1) => {
  console.log("This person's " + key + " is " + person[key] + ".");
};

showPersonsProperty(person1, "name");
// [LOG]: "This person's name is Mike."

showPersonsProperty(person1, "age");
// [LOG]: "This person's age is 35."
Enter fullscreen mode Exit fullscreen mode

Perfect! We could skip defining the Person interface by referring to the person1 object.
You can use typeof to retrieve the type of a value. (Please keep in mind that this typeof is the operator provided by TypeScript. It means this operator does not exist in runtime.)

keyof typeof

You might wonder what is keyof typeof. Good question!
Let me explain this advanced technique.
By chaining these two operators, you can retrieve the keys of an object variable as Union type.

First, the Object type is retrieved by typeof objectVariable. Second, keys of the Object type are extracted by the keyof operator. Finally, these keys will be a literal union type.

By using the type operators, we will be able to write more concise code!

Top comments (0)