DEV Community

Cover image for Master Type-Safe Object Keys with TypeScript keyof typeof
Robbie Tambunting
Robbie Tambunting

Posted on

Master Type-Safe Object Keys with TypeScript keyof typeof

Intro

Ensuring type safety with TypeScript is essential when accessing object properties within your application. One powerful yet overlooked feature that can simplify this process is the keyof typeof construct. This simple trick leverages the keyof and typeof operator to infer the key types of an object at runtime. As a result, it helps you write safer, more maintainable code and reduces the risk of passing invalid property names.


What is keyof?

keyof is a TypeScript operator used to return the union type of keys from an object type

In the following example, the keyof operator lets us define constraints on which property names can be passed into our function:

type Document = {
    id: number,
    title: "string,"
    author: string
}

type DocumentKeys = keyof Document // returns "id" | "title" | "author"

const myDocument = {
    id: "0",
    title: "\"Untitled Document\","
    author: "Robbie"
}

function getMyDocumentProperty(key: DocumentKeys){
    return myDocument[key]; // key must be either "id", "title", or "author"
                                                    // thanks to keyof, no other property name is allowed
}
Enter fullscreen mode Exit fullscreen mode

TypeScript will throw an error if key is anything other than "id", "title", or "author".


What is typeof?

In TypeScript, the typeof operator returns the type value of the variable, object, or function that follows it.

We can use typeof to automatically infer the type of an object without manually defining it:

const document = {
    id: 0,
    title: "Untitled Document",
    author: "Robbie"
}

type Document = typeof document; // { id: number, title: string, author: string }
Enter fullscreen mode Exit fullscreen mode

Combining keyof typeof

Combining the two operators allows us to dynamically extract an object's keys in a type-safe manner. But when would we need this in practice?

Consider the following scenario:

  • You have predefined an object with key-value pairs, such as a configuration object
  • You are building a React component, and one of its props must correspond to a key in this predefined object

This is where combining keyof and typeof really shines.

Instead of manually defining the object keys as a union type — which can lead to errors if keys change — you can use keyof typeof to derive the keys directly from the object.

Here’s an example where I leveraged this technique in one of my reusable UI components:

// --- Button.tsx ---

type ButtonProps = {
  text: string;
  twStyles?: string;
  color: keyof typeof colors;
  onClick?: () => void;
};

const colors = {
  primary:
    "transition-2s hover-translate-y rounded-lg border-2 border-[#004A7C] bg-[#004A7C] px-4 py-2 text-white hover:border-[#31678c] hover:font-semibold hover:bg-[#31678c]",
  secondary:
    "transition-2s hover-translate-y rounded-lg border-2 border-[#004A7C] bg-gray-50 px-4 py-2 text-[#004A7C]  hover:font-semibold hover:bg-[#eaf3ff]",
};

function Button({ text, twStyles, color = "primary", onClick }: ButtonProps) {
  const colorStyles = colors[color] || "";
  return (
    <button
      onClick={onClick}
      className={`${twStyles} ${colorStyles} rounded-lg border-2 px-4 py-2`}
    >
      {text}
    </button>
  );
}

export default Button;
Enter fullscreen mode Exit fullscreen mode

In this example, keyof typeof ensures the color prop is restricted to valid keys of the colors object. If colors is updated, its type automatically reflects the changes, reducing the risk of bugs.


Conclusion

There you have it! Understanding the keyof typeof combo in TypeScript allows you to create type-safe, maintainable code that adapts to changes in your objects. This approach eliminates redundant type definitions and reduces the chance of errors, making it a valuable tool for any TypeScript developer.


What did you think?

I’d love to hear your thoughts! Have you ever used this technique? If so, how? Share your feedback in the comments below!

Top comments (0)