Using keyof for Dynamic Access in TypeScript
Learn how to use the keyof operator to extract keys from your interfaces, enabling type-safe dynamic property access that prevents runtime typos.

Previously in this course, we explored constraining generics to build reusable components. In this lesson, we add the keyof operator to our toolkit, which allows us to bridge the gap between hardcoded object shapes and dynamic runtime data access.
The Problem: Fragile Dynamic Access
In JavaScript, accessing object properties dynamically is common. You might have a helper function that updates a specific field on a Task object, like so:
JAVASCRIPTfunction updateTask(task, key, value) { task[key] = value; // Danger: TypeScript doesnCE9178">'t know if 'key' exists! }
If you pass a key like "priorityLevel" but your Task interface only defines "priority", you create a silent bug. Even worse, if you mistype the string, the function fails silently at runtime. We need a way to tell TypeScript: "This string must be one of the keys of this object."
Using Keyof for Type Safety
The keyof operator takes an object type and produces a union of its literal keys. If you have an interface, keyof turns it into a "whitelist" of valid property names.
Let's apply this to our ongoing Task API client project.
TYPESCRIPTinterface Task { id: string; title: string; isCompleted: boolean; } // Resulting type: "id" | "title" | "isCompleted" type TaskKey = keyof Task;
Now, we can constrain our updateTask function to only accept valid keys of the Task object.
Worked Example: A Type-Safe Setter
Let's refine our function signature using generics and the keyof operator. This ensures that the key argument is strictly tied to the properties of the provided object.
TYPESCRIPTinterface Task { id: string; title: string; isCompleted: boolean; } function updateTask<T, K extends keyof T>(obj: T, key: K, value: T[K]) { obj[key] = value; } const myTask: Task = { id: "1", title: "Learn TS", isCompleted: false }; // Valid calls updateTask(myTask, "title", "Mastering keyof"); // Success updateTask(myTask, "isCompleted", true); // Success // Invalid calls(TypeScript will throw an error) // updateTask(myTask, "description", "Oops"); // Error: CE9178">'description' is not a key of Task // updateTask(myTask, "id", 123); // Error: Argument 123 is not assignable to string
By using T[K], we are performing an indexed access type, which tells TypeScript that the value must match the type of the specific property found at key.
Hands-on Exercise
- Take your existing
Taskinterface from previous lessons. - Write a function called
getTaskValuethat takes aTaskobject and a key, and returns the value of that key. - Ensure the return type of the function is correctly inferred based on the key provided.
- Try to pass a non-existent key to the function and observe the red squiggly line in your editor.
Common Pitfalls
- Forgetting Generics: If you don't use a generic
<T>,keyofwill be tied to a specific interface, making your utility function non-reusable. Always usekeyof Twhen writing generic utilities. - Assuming Keyof works on Instances: Remember that
keyofoperates on types (interfaces/aliases), not runtime objects. You must usekeyof typeof myObjectif you want to extract keys from a plain object variable without an interface. - Over-complicating: If you are only accessing one or two known properties, don't force a
keyofabstraction. It is best used for generic utilities, filters, or form handlers.
FAQ
Can I use keyof with arrays?
Yes. keyof string[] will include "length", "push", "pop", and other array methods.
What if I need to handle keys that don't exist yet? Check out our lesson on TypeScript index signatures to learn how to allow arbitrary dynamic keys while maintaining safety.
How does this relate to mapped types?
keyof is the foundation of Mapped Types. You use keyof to iterate over the keys of an object to transform them, which we'll cover in Preventing Runtime Property Errors with TypeScript Mapped Types.
Recap
The keyof operator is your primary tool for enforcing constraints on dynamic property access. By combining keyof with generics, you create APIs that are self-documenting and resilient against typos.
Up next: We'll explore Indexed Access Types to extract specific property types from our interfaces.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 โ from idea to deployed product, by an engineer who ships to production.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js โ charts, tables, and real-time data that your users will actually enjoy using.

