Skip to content
Laviyx Learn

Try

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.

Advanced8 min readUpdated
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:

TypeScript
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");
Output
email: asha@example.com
TypeScript
type User = { id: number; name: string };
const key: keyof User = "age";
Compiler error
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:

TypeScript
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);
Output
shipped 2 42
  • Order["items"] is the array type; adding [number] gives the type of one element (indexing with number means "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:

TypeScript
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 }));
Output
{
  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:

TypeScript
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);
Output
Ravi 2026-10-24

keyof 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:

TypeScript
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"));
Output
₹499.00 $12.00

Adding 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#

TypeScript
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);
Output
Meera team

Summary#

OperatorInputOutputExample
keyof TA typeUnion of its property nameskeyof User → "id" | "name"
T[K]A type and key(s)Type of those propertiesUser["name"] → string
T[number]An array or tuple typeElement typestring[][number] → string
typeof vA valueIts typetypeof settings

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
TypeScript
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"));
Output
/ /courses/:id

Key takeaway#

Finished this lesson?