TYPESCRIPT

TypeScript Keyof Type Operator: Syntax, Use Cases, and Examples

The TypeScript keyof operator is a powerful tool for extracting the names of properties from a type or interface. By applying keyof TypeScript to a type, you can create a union of its keys, which you can then use for type-safe property access, utility types, and advanced generics. This operator is essential for writing flexible and reusable TypeScript code.

In this guide, we’ll explore how the keyof operator works, how to combine it with other TypeScript features, and what practical use cases it unlocks. You’ll learn how to apply TypeScript keyof to objects, interfaces, enums, and more, and how to use it for type inference, constraints, and transformation.


What Is the TypeScript Keyof Operator?

The keyof operator in TypeScript takes an object type and returns a union of its keys.

Example:

ts
CopyEdit
type User = {
  id: number;
  name: string;
  email: string;
};

type UserKeys = keyof User; // "id" | "name" | "email"

The type UserKeys is now a union of the keys of User. You can use this for key-safe operations such as mapping, property access, and generics.


Using TypeScript Keyof on Objects

When working with plain objects, typescript keyof object helps derive the set of valid keys.

ts
CopyEdit
const user = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
};

type Keys = keyof typeof user; // "id" | "name" | "email"

By using typeof on the object, you get its type, and keyof then extracts the key names.

This is especially useful in functions that operate generically on objects.


Keyof with Interfaces

When applied to interfaces, keyof TypeScript yields a union of all defined property names.

ts
CopyEdit
interface Product {
  title: string;
  price: number;
  inStock: boolean;
}

type ProductKeys = keyof Product; // "title" | "price" | "inStock"

This helps with utility types like Pick, Record, or in building strongly typed form inputs.


Type Constraints Using Extends Keyof TypeScript

When creating generic functions or components, you can constrain a type parameter to valid keys using extends keyof.

ts
CopyEdit
function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const book = { title: "1984", author: "Orwell" };
const title = getValue(book, "title"); // Valid

This pattern ensures that key must be one of the keys of the object, preventing typos or invalid access.

Using extends keyof TypeScript this way helps you write safe and reusable generic code.


Keyof with Index Signatures

When you use index signatures, keyof can produce string or number unions depending on how the keys are typed.

ts
CopyEdit
type Collection = {
  [id: number]: string;
};

type CollectionKey = keyof Collection; // number

This helps when working with numeric indexes like arrays or key-based maps.


As Keyof TypeScript

The as keyof expression allows you to cast values or variables to a union of keys, enabling type-safe access patterns.

Example:

ts
CopyEdit
function logField<T>(obj: T, field: string) {
  const key = field as keyof T;
  console.log(obj[key]);
}

This cast tells TypeScript to treat field as a key of the object, which may be necessary in loosely typed code.

Use it cautiously, as it circumvents full compile-time safety.


Keyof and Typeof Combined

A powerful pattern involves using keyof with typeof to operate on runtime values with static typing.

ts
CopyEdit
const settings = {
  darkMode: true,
  volume: 70,
  notifications: false,
};

type SettingsKey = keyof typeof settings; // "darkMode" | "volume" | "notifications"

This helps in dynamic components where fields or controls are generated based on configuration objects.


Keyof Enum TypeScript

The keyof operator can be applied to enums, but it behaves differently depending on how the enum is defined.

Example:

ts
CopyEdit
enum Status {
  Active = "active",
  Inactive = "inactive",
}

type StatusKeys = keyof typeof Status; // "Active" | "Inactive"

You get the keys as strings, not the values. Use this to iterate over or validate enum property names.

To get enum values instead, you'd use:

type StatusValues = typeof Status[keyof typeof Status]; // "active" | "inactive"

Keyof with Mapped Types

You can use keyof TypeScript in combination with mapped types to iterate and transform keys.

Example:

type Original = {
  id: number;
  name: string;
};

type Nullable<T> = {
  [K in keyof T]: T[K] | null;
};

type NullableOriginal = Nullable<Original>;

This allows you to build flexible utility types that operate generically over any structure.


Type Guards Using Keyof

You can also build safe type guards using keyof to check the presence of keys.

function hasKey<T>(obj: T, key: keyof T): boolean {
  return key in obj;
}

This works well with optional properties and dynamic field access in large schemas.


Excluding or Picking Keys

You can use keyof with Exclude, Pick, or Omit to include or remove properties by name.

type Person = {
  name: string;
  age: number;
  password: string;
};

type PublicKeys = Exclude<keyof Person, "password">;
type PublicInfo = Pick<Person, PublicKeys>;

This keeps only name and age, omitting sensitive fields dynamically using keys.


Keyof with Nested Structures

While keyof works on the top-level of a type, it doesn’t automatically traverse nested structures. You can use helper types to dig deeper.

type Nested = {
  user: {
    id: number;
    name: string;
  };
};

type UserKeys = keyof Nested["user"]; // "id" | "name"

This lets you drill into nested properties safely and compose types based on internal structures.


Building Forms and Components with Keyof

In UI development, especially with frameworks like React, TypeScript keyof is commonly used to tie form inputs or component props to object keys.

type FormFields = {
  username: string;
  email: string;
};

function renderField<K extends keyof FormFields>(field: K, value: FormFields[K]) {
  return `<input name="${field}" value="${value}" />`;
}

This ensures that every rendered field corresponds to a valid property in the type.


Using Keyof with Record Utility

keyof can help define valid keys in a Record structure.

type Permissions = "read" | "write" | "delete";
type RolePermissions = Record<Permissions, boolean>;

const admin: RolePermissions = {
  read: true,
  write: true,
  delete: true,
};

Here, Permissions is derived from a literal type, but you could also use keyof SomeType as the key set.

Learn TypeScript for Free
Start learning now
button icon
To advance beyond this tutorial and learn TypeScript by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH

Reach your coding goals faster