Pick Utility Type in TypeScript

Pick creates a new type by selecting only the properties you name from an existing type. Use it to build focused types for specific views, API responses, or function parameters.

6 min read

Pick<T, K> is a built-in utility type that creates a new type by selecting specific properties from an existing type. You pass it a type and a union of property names, and it returns a type with only those properties.

This is one of the most practical utility types. Most applications have a large data model type, like User or Product, but different parts of the code only need a few fields.

Pick lets you create precise, focused types from one source of truth.

typescripttypescript
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
  createdAt: Date;
}
 
type PublicProfile = Pick<User, "id" | "name">;
 
const profile: PublicProfile = {
  id: 1,
  name: "Ada",
};

PublicProfile only has id and name. The compiler rejects any attempt to add email, password, or createdAt. This is safer than passing the full User type to a public-facing function where sensitive fields should never be accessed.

How Pick works

Pick takes two arguments. The first is the source type. The second is a union of string literal types that must be keys of the source type. If you try to pick a key that does not exist, TypeScript reports an error:

typescripttypescript
interface Product {
  title: string;
  price: number;
}
 
type Bad = Pick<Product, "title" | "rating">;
 
// Output:
// Type '"title" | "rating"' does not satisfy the constraint 'keyof Product'.
//   Type '"rating"' is not assignable to type 'keyof Product'.

TypeScript checks that every key you name actually exists on the source type. This catches typos and prevents you from accidentally referencing fields that are not there.

Pick for API response types

A common pattern is using Pick to define the shape of API responses. Your database model might have many columns, but each endpoint only returns a subset.

typescripttypescript
interface Article {
  id: number;
  title: string;
  body: string;
  authorId: number;
  status: string;
  publishedAt: Date;
}

A list endpoint usually returns lightweight items, while a detail endpoint returns a richer view with more fields. Both response types can derive from the same Article interface using Pick with a different set of keys for each:

typescripttypescript
type ArticleListItem = Pick<Article, "id" | "title" | "publishedAt">;
type ArticleDetail = Pick<Article, "id" | "title" | "body" | "publishedAt">;

Adding a field to Article makes it available to both response types automatically. You never need to update the derived types unless you want to explicitly exclude a new field.

Pick for function parameters

Functions that only need a few fields from a large object should use Pick in their parameter types. This makes the function's requirements explicit and self-documenting.

typescripttypescript
interface Order {
  orderId: string;
  customerName: string;
  email: string;
  items: string[];
  total: number;
  status: string;
}

A confirmation email function only needs three of these fields: the address to send to, the customer's name, and the order id for the subject line. Using Pick on the parameter type says exactly that, instead of accepting the entire Order object:

typescripttypescript
function sendConfirmation(
  order: Pick<Order, "email" | "customerName" | "orderId">
) {
  console.log(
    `Sending to ${order.email}: Order ${order.orderId} confirmed for ${order.customerName}`
  );
}

You can still pass a full Order object because it has all the required properties. TypeScript's structural typing allows this: an object with more properties satisfies a type that needs fewer.

Combining Pick with Partial

Pick and Partial utility type in TypeScript work well together. Use Pick to select the editable fields, then Partial to make them optional for an update:

typescripttypescript
interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}
 
// id and password are never editable through this update function
type EditableFields = Partial<Pick<User, "name" | "email">>;
 
function updateUser(user: User, fields: EditableFields): User {
  return { ...user, ...fields };
}

The id and password are excluded from EditableFields entirely. Only name and email can be updated, and both are optional. This is more precise than using Partial<User>, which would also make id and password optional.

Pick with keyof for type-safe field selection

Sometimes you want to pick fields dynamically but still get type checking. The keyof operator gives you all the keys of a type as a union:

typescripttypescript
function pluck<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  for (const key of keys) {
    result[key] = obj[key];
  }
  return result;
}
 
const user = { id: 1, name: "Ada", email: "ada@example.com" };
const subset = pluck(user, ["id", "name"]);
// subset has type { id: number; name: string; }

The function is generic. K is constrained to be keys of T, so you cannot pass a key that does not exist. The return type is Pick<T, K>, so the result has exactly the fields you requested. For more on keyof, see keyof operator in TypeScript.

Common mistakes

Duplicating types instead of using Pick. If you find yourself writing a new interface with the same fields as an existing one, use Pick instead. It keeps your types in sync and reduces duplication.

Picking too many fields. If you pick most of the properties, consider using Omit utility type in TypeScript instead to remove the few you do not want. The result is often more readable.

Forgetting that Pick does not validate at runtime. Pick is a compile-time construct. If you receive JSON from an API and type it as Pick<User, "name">, the compiler trusts you. The actual object might be a full User or something completely different. Validate at runtime when data comes from outside your code.

Rune AI

Rune AI

Key Insights

⚠ This article has a formatting issue and may not display correctly.

Our team has been notified. The content is shown as plain text below.

- Pick creates a new type with only the properties named in K. - The second argument is a union of string literals matching the keys of T. - Pick keeps a connection to the source type. Changes to the original flow through. - Combine Pick with Partial to make selected properties optional. - Use Pick instead of writing separate smaller interfaces when the fields come from a shared source.
RunePowered by Rune AI

Frequently Asked Questions

Can I use Pick with a single property?

Yes. `Pick<User, 'id'>` creates a type with only the id property. The second argument can be a single string literal or a union of string literals.

What happens if I try to Pick a property that does not exist on the type?

The compiler reports an error. TypeScript checks that every key in the union exists on the source type. You cannot pick a property that is not there.

Is Pick the same as creating a new interface with only those properties?

Functionally yes, but Pick keeps the connection to the original type. If the original type changes, the picked type updates automatically. A separate interface needs to be maintained by hand.

Conclusion

Pick lets you create a smaller type by choosing only the properties you need from a larger type. It keeps your types in sync with a single source of truth. Use it for API response types, form data types, and any function that only needs a subset of an object's fields.