Utility Types Partial Pick Omit
Use Partial, Required, Pick, Omit, and Record to reshape props and DTOs without rewriting object types by hand.
- typescript
- utility-types
TypeScript ships utility types that transform existing types. Partial, Pick, Omit, Required, and Record cover most day-to-day frontend reshaping: form drafts, API patches, prop subsets, and dictionaries.
Docs: Utility Types.
Source type
type User = {
id: string;
name: string;
email: string;
role: 'admin' | 'user';
};
Partial<T> — all optional
type UserDraft = Partial<User>;
// { id?: string; name?: string; email?: string; role?: … }
function updateUser(id: string, patch: Partial<Omit<User, 'id'>>) {
return fetch(`/users/${id}`, {
method: 'PATCH',
body: JSON.stringify(patch),
});
}
Required<T> — all required
type Hydrated = Required<UserDraft>;
Useful after defaults are applied.
Pick<T, K> — keep keys
type UserPreview = Pick<User, 'id' | 'name'>;
// { id: string; name: string }
Omit<T, K> — drop keys
type UserCreate = Omit<User, 'id'>;
// client creates without id
Omit is Pick with the complement of keys.
Record<K, V> — key → value map
type Roles = Record<User['role'], string[]>;
// { admin: string[]; user: string[] }
const permissions: Roles = {
admin: ['read', 'write', 'billing'],
user: ['read'],
};
Composing utilities
type PublicUser = Omit<User, 'email'>;
type OptionalPublic = Partial<PublicUser>;
type NameOnly = Pick<Required<User>, 'name'>;
Prefer small readable aliases over nested one-liners in public APIs.
React props patterns
type ButtonProps = {
variant: 'primary' | 'secondary';
size: 'sm' | 'md';
children: React.ReactNode;
onClick: () => void;
};
// Storybook / tests: override some props
type ButtonStory = Partial<ButtonProps> & Pick<ButtonProps, 'children'>;
// Extend native button without redeclaring everything
type IconButtonProps = Omit<
React.ComponentPropsWithoutRef<'button'>,
'children'
> & {
label: string; // accessible name
icon: React.ReactNode;
};
What they don’t do
Utilities are type-level. They don’t strip fields at runtime:
const user: User = { /* … */ };
const preview: UserPreview = user; // ok structurally
// runtime still has email if you JSON.stringify(user)
Use mappers for wire format.
Other utilities worth knowing
| Utility | Role |
|---|---|
Readonly<T> |
all props readonly |
NonNullable<T> |
drop null|undefined |
ReturnType<F> |
function return |
Parameters<F> |
param tuple |
Extract / Exclude |
filter unions |
Footguns
Omiton unions — distributes in ways that surprise; test.Partialfor incomplete domain objects — may hide required invariants.- Stringly
Pick<User, string>— invalid; keys must be key types. - Deep partial — shallow only; nest explicitly or use a DeepPartial helper.
Interview out-loud answer
“Partial makes fields optional for patches, Pick/Omit carve prop and DTO shapes, Record builds typed maps. I compose them for forms and API clients, and I remember they erase at runtime — serialization still needs real field selection.”
Omit and union distribution
Omit distributed over unions can produce unexpected shapes. When omitting from a union of object types, verify the result on each member or remodel with discriminants. Add a quick type-level test via Expect<Equal<…>> helpers if the shape is critical.
Related on this site
- Record and Partial patterns for forms
- Mapped types intro
- Typing React props
- keyof typeof and indexed access
- Readonly and const assertions
Further reading
Related guides
- Basic Types and AnnotationsPrimitives, arrays, objects, and function annotations TypeScript actually checks — plus where inference is enough and where it is not.
- Branded Types for IDsNominal-style UserId vs OrderId in TypeScript — prevent ID mixups at compile time with brands, parsers, and form boundaries.
- Conditional Types IntroT extends U ? X : Y — how TypeScript picks types from conditions, distributes over unions, and powers utility types you already use.
- Declaration Files and DefinitelyTypedHow .d.ts files describe JS to TypeScript, when to use @types packages, module augmentation, and writing minimal ambient types for untyped libs.
- Discriminated Unions for UI StateModel loading, success, and error as mutually exclusive variants so TypeScript and your UI cannot show impossible states.