These two operators let you derive types from existing types and values — the foundation of type-level programming.
keyof — the union of an object type's keys
interface User { id: number; name: ; }
= keyof ;
const config = { host: "localhost", port: 3000 };
type Config = typeof config; // { host: string; port: number }
typeof (in a type position) captures the inferred type of a runtime value, so you don't have to write the type out separately.
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const user = { id: 1, name: "Ann" };
getProp(user, "name"); // returns string
getProp(user, "age"); // ❌ Error: "age" is not a key of user
Here K extends keyof T restricts key to real keys, and T[K] (an indexed access type) gives back the exact value type for that key. Typos become compile errors.
const Roles = { Admin: "admin", User: "user" } as const;
type Role = typeof Roles[keyof typeof Roles]; // "admin" | "user"
keyof and typeof connect the value world and the type world.
They power type-safe property access, deriving types from config/constants (single source of truth), and are building blocks for mapped and conditional types.
They're how you avoid hand-maintaining parallel type definitions.
A library of IT interview questions with detailed answers — from Junior to Senior.
Donate