Skip to main content
Go back

TypeScript #5: The Magic of typeof and keyof

#typescript #typeof #keyof

How to create types from values and forget about manually keeping types in sync.

Here is where TypeScript stops being “JavaScript with types” and becomes a superpower. Until now we have defined types manually. But what if we could automatically generate types from our code?

typeof: Extracting the DNA

In JS, typeof returns a string (“string”, “number”, “object”). In TS, if we use it in a type context, it returns the full type.

typescript
const settings = {
  theme: "dark",
  notifications: true,
  version: 1.0
};

// Instead of writing the interface manually...
// type Settings = { theme: string; notifications: boolean; version: number }; 😴

type Settings = typeof settings; 
// 🪄 Boom! TS just wrote the interface for you.

This is brutal for APIs or third-party libraries (or our own configuration constants). We have a “Single Source of Truth”: the value. The type adapts itself.

API Trick

Imagine you have a JSON response from an API. Instead of writing the interface by hand, you can paste the JSON as a constant (mock) and extract the type from there. Thus, the example serves as documentation and type generator at the same time.

keyof: Give me the keys

keyof takes a Type and returns a Union of its keys.

typescript
interface User {
  name: string;
  age: number;
  email: string;
}

type UserKeys = keyof User;
// It is equivalent to: "name" | "age" | "email"

What is it for? So that we cannot ask for properties that do not exist.

typescript
function getProperty(user: User, key: keyof User) {
  return user[key];
}

const me: User = { name: "Alice", age: 39, email: "..." };

getProperty(me, "name"); // ✅
getProperty(me, "password"); // ❌ Error: Argument of type '"password"' is not assignable...

The Ultimate Combo: keyof typeof

This is one of the most used combinations in real TypeScript. It is used when we want to get the keys of an object/value that already exists (not an interface).

  1. typeof object -> Gives us the Type of the object.
  2. keyof (Type) -> Gives us the keys of that Type.
typescript
const COLORS = {
  red: "#FF0000",
  green: "#00FF00",
  blue: "#0000FF"
};

type ColorName = keyof typeof COLORS;
// "red" | "green" | "blue"

function paint(color: ColorName) { ... }

paint("red"); // ✅
paint("yellow"); // ❌ Error

Let’s try it!

Let’s use the editor. Let’s create a config object with various options. Let’s use typeof to extract its type and create a function that receives that type.

In Part 6 we will see Generics, the tool that allows us to create reusable components and functions that work with any type (the famous <T>).