ESC

Type to search the knowledge base.

Utility Types Partial Pick Omit

Use Partial, Required, Pick, Omit, and Record to reshape props and DTOs without rewriting object types by hand.

beginner3 min read
  • 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

  1. Omit on unions — distributes in ways that surprise; test.
  2. Partial for incomplete domain objects — may hide required invariants.
  3. Stringly Pick<User, string> — invalid; keys must be key types.
  4. 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.

Further reading

Related guides