Pick<T, K> is a built-in utility type that creates an object type with only the properties of T named in K. Use it when a function or component needs a few fields of a bigger type:
renderPreview accepts a full User and also a plain { id, name } object, because it asks for only what it uses. That makes it easier to call and to test. Pick is type-only: the full ada object still has all five properties at runtime.
Syntax and Key Checking
Pick<Type, Keys>
Keys is a single key or a union of keys, and each one must exist on Type. The definition in TypeScript's standard library makes that a constraint:
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
Because of K extends keyof T, a misspelled or missing key is a compile error, and your editor can autocomplete the key names:
The error is error TS2344: Type '"cost"' does not satisfy the constraint 'keyof Product'. This is a difference from Omit, whose keys are not checked.
Pick Keeps readonly and Optional
Pick maps over keys of T, so each picked property keeps its modifiers:
The last line shows { id: 8 } because readonly is a compile-time check only: the assignment was reported, suppressed with @ts-expect-error, and still ran. To change the modifiers as you pick, wrap the result: Partial<Pick<Account, "plan">> or Required<Pick<Account, "email">>.
Pick vs Omit
Pick names what to keep; Omit names what to drop. Both give the same result today, but they behave differently when the source type grows:
Pick<T, K> | Omit<T, K> | |
|---|---|---|
| You list | the keys to keep | the keys to remove |
New properties on T | not included | included automatically |
Unknown key in K | compile error (TS2344) | accepted silently |
| Good for | API responses, public views, props | "everything except the secret" |
For data that leaves your server, Pick is the safer default: nothing appears in the type unless someone added it on purpose.
Picking from Nested Types
Pick only sees top-level keys: a dotted path like Pick<Customer, "address.city"> is an error (TS2344), not a nested pick. Use an indexed access type to reach the nested type, then pick from it:
Customer["address"] is the type of the address property. The same syntax reaches array elements: for an orders: Order[] property, Customer["orders"][number] is Order.
A Typed pick() Function
Pick does nothing at runtime. A small generic function copies the chosen properties into a new object and returns exactly Pick<T, K>:
K extends keyof T lets TypeScript infer K from the string arguments, so the return type has exactly the picked keys. The {} as Pick<T, K> assertion is needed because an empty object does not have those properties yet; the loop fills them in.
Picking Properties by Value Type
Pick selects by key name. To select by the property's type, for example "all the string fields", write a mapped type with a key filter:
The as clause maps each key to itself when its type matches and to never otherwise, and never keys are dropped. One subtlety: an optional property's type includes undefined, so an optional subtitle?: string would not count as string here; test against string | undefined to include it.
Frequently Asked Questions
What does Pick do in TypeScript?
Pick<T, K> builds an object type containing only the properties of T whose keys are in K. Pick<User, "id" | "name"> is { id: number; name: string } when User has those two properties plus others. It works on types only and removes nothing from objects at runtime.
What is the difference between Pick and Omit?
Pick lists the properties to keep, Omit lists the ones to remove. When the source type gains a property, Omit includes it automatically and Pick does not. Pick also checks that its keys exist on the type; Omit accepts any key.
How do I pick multiple properties in TypeScript?
Pass a union of keys: Pick<User, "id" | "name" | "email">. The keys must all exist on User, or the compiler reports error TS2344.
How do I pick a nested property in TypeScript?
Pick only selects top-level properties. Reach into a nested type with an indexed access type and pick from that: Pick<User["address"], "city">. To keep the nesting, combine them: Pick<User, "id"> & { address: Pick<User["address"], "city"> }.
Does Pick keep readonly and optional modifiers?
Yes. Pick is a mapped type over keys of T, so a property that is readonly or optional in T stays that way in the picked type.