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.
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.
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:
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.
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:
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.
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:
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:
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:
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
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.
Frequently Asked Questions
Can I use Pick with a single property?
What happens if I try to Pick a property that does not exist on the type?
Is Pick the same as creating a new interface with only those properties?
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.
More in this topic
TypeScript Compiler Explained
The TypeScript compiler (tsc) turns .ts files into .js files while checking types. Learn what it does, how to use it, and how it fits your workflow.
Set Up ESLint for TypeScript
Install and configure ESLint with typescript-eslint to catch bugs and enforce consistent code style in your TypeScript project.
Create a tsconfig File
A tsconfig.json file tells TypeScript how to compile your project. Learn how to create one, what the key sections mean, and which options to set first.