TypeScript course menu
TypeScript keyof, typeof and Indexed Access Types
Learn TypeScript's type operators: keyof for unions of property names, typeof to get a type from a value, indexed access types like Person['age'], combining them for constants and configuration objects, and element types of arrays.
On this page
TypeScript has operators that create new types from existing types and values. Three of them are the foundation for all the advanced types in this section.
keyof: the property names of a type#
keyof T produces a union of the property names of T:
type User = { id: number; name: string; email: string };
type UserKey = keyof User; // "id" | "name" | "email"
function printField(user: User, key: UserKey): void {
console.log(`${key}: ${user[key]}`);
}
printField({ id: 1, name: "Asha", email: "asha@example.com" }, "email");email: asha@example.comtype User = { id: number; name: string };
const key: keyof User = "age";error TS2322: Type '"age"' is not assignable to type 'keyof User'.When a property is added to User, keyof User updates automatically.
Indexed access: the type of a property#
T["key"] gives the type of a property, just as obj["key"] gives its value:
type Order = {
id: number;
status: "placed" | "shipped" | "delivered";
items: { name: string; qty: number }[];
};
type OrderStatus = Order["status"]; // "placed" | "shipped" | "delivered"
type OrderItem = Order["items"][number]; // { name: string; qty: number }
type IdOrStatus = Order["id" | "status"]; // number | "placed" | "shipped" | "delivered"
const s: OrderStatus = "shipped";
const item: OrderItem = { name: "Pen", qty: 2 };
const value: IdOrStatus = 42;
console.log(s, item.qty, value);shipped 2 42Order["items"]is the array type; adding[number]gives the type of one element (indexing withnumbermeans "any numeric index").- Indexing with a union gives a union of property types.
This keeps related types in sync: if the status options change, OrderStatus follows.
typeof: the type of a value#
In a type position, typeof value gives the type TypeScript inferred for a variable:
const defaultSettings = {
theme: "light",
fontSize: 16,
notifications: { email: true, sms: false },
};
type Settings = typeof defaultSettings;
// { theme: string; fontSize: number; notifications: { email: boolean; sms: boolean } }
function merge(overrides: Partial<Settings>): Settings {
return { ...defaultSettings, ...overrides };
}
console.log(merge({ fontSize: 20 }));{
theme: 'light',
fontSize: 20,
notifications: { email: true, sms: false }
}The value is the single source of truth, and the type is derived from it. (Partial makes every property optional; see Utility Types.)
This is TypeScript's typeof, used in types. JavaScript's typeof operator, used in expressions (typeof x === "string"), still works normally in code.
typeof also works on functions, with the utility types ReturnType and Parameters:
function createUser(name: string, age: number) {
return { name, age, createdAt: "2026-10-24" };
}
type NewUser = ReturnType<typeof createUser>; // { name: string; age: number; createdAt: string }
type CreateArgs = Parameters<typeof createUser>; // [name: string, age: number]
const args: CreateArgs = ["Ravi", 31];
const u: NewUser = createUser(...args);
console.log(u.name, u.createdAt);Ravi 2026-10-24keyof typeof: keys of an object value#
Combining the two gives the keys of an object value, a very common pattern for lookup tables and constants:
const currencySymbols = {
INR: "₹",
USD: "$",
EUR: "€",
} as const;
type Currency = keyof typeof currencySymbols; // "INR" | "USD" | "EUR"
type SymbolValue = (typeof currencySymbols)[Currency]; // "₹" | "$" | "€"
function format(amount: number, currency: Currency): string {
return `${currencySymbols[currency]}${amount.toFixed(2)}`;
}
console.log(format(499, "INR"), format(12, "USD"));₹499.00 $12.00Adding a currency to the object automatically adds it to the Currency type. This is the same technique used for as const objects in Enums.
Array element types#
const PLANS = ["free", "pro", "team"] as const;
type Plan = (typeof PLANS)[number]; // "free" | "pro" | "team"
const people = [{ name: "Asha", age: 21 }];
type Person = (typeof people)[number]; // { name: string; age: number }
const p: Person = { name: "Meera", age: 28 };
const plan: Plan = "team";
console.log(p.name, plan);Meera teamSummary#
Practice#
Practice exercise
Given const ROUTES = { home: "/", courses: "/courses", course: "/courses/:id" } as const, derive RouteName (the keys) and RoutePath (the values), and write pathFor(name: RouteName): RoutePath. Print the paths for home and course.
Show solution
const ROUTES = {
home: "/",
courses: "/courses",
course: "/courses/:id",
} as const;
type RouteName = keyof typeof ROUTES;
type RoutePath = (typeof ROUTES)[RouteName];
function pathFor(name: RouteName): RoutePath {
return ROUTES[name];
}
console.log(pathFor("home"), pathFor("course"));/ /courses/:idKey takeaway#
Finished this lesson?