TypeScript Utility Types

TypeScript utility types are built-in generic types that transform other types. Instead of writing a new type by hand, you derive it from an existing one, so changes stay in sync automatically.

Partial and Required

Partial<T> makes every property optional, which is ideal for update functions. Required<T> does the opposite.

type Product = { id: number; name: string; price: number };

function update(p: Product, changes: Partial<Product>): Product {
  return { ...p, ...changes };
}
const tea: Product = { id: 2, name: "Green Tea", price: 6 };
console.log(update(tea, { price: 6.5 }));
{ id: 2, name: 'Green Tea', price: 6.5 }

Pick and Omit

Pick<T, Keys> keeps only the listed properties; Omit<T, Keys> removes them. They are great for API payloads and public views of data.

type User = { id: number; name: string; email: string; password: string };

type PublicUser = Omit<User, "password">;
type LoginForm = Pick<User, "email" | "password">;

const shown: PublicUser = { id: 1, name: "Sara", email: "sara@example.com" };
const form: LoginForm = { email: "sara@example.com", password: "secret" };
console.log(Object.keys(shown).join(","), "|", Object.keys(form).join(","));
id,name,email | email,password

Readonly and Record

Record<K, V> builds an object type with keys K and values V. With a union of keys, TypeScript requires every key to be present. Readonly<T> blocks reassignment of properties.

type Country = "PK" | "UK" | "US";
const dialCodes: Readonly<Record<Country, string>> = {
  PK: "+92",
  UK: "+44",
  US: "+1",
};
// dialCodes.PK = "0"; // Error: Index signature is read-only.
console.log(dialCodes.UK);
+44

ReturnType, Parameters and Awaited

These utilities extract types from functions. Awaited unwraps the value inside a promise.

async function loadUser(id: number) {
  return { id, name: "Omar", roles: ["admin"] };
}
type LoadArgs = Parameters<typeof loadUser>;            // [id: number]
type UserData = Awaited<ReturnType<typeof loadUser>>;   // { id: number; name: string; roles: string[] }

const u: UserData = { id: 9, name: "Liam", roles: [] };
const args: LoadArgs = [9];
console.log(u.name, args[0]);
Liam 9

More Built-in Utility Types

  • NonNullable<T>: removes null and undefined
  • Exclude<T, U>: removes members of a union that match U
  • Extract<T, U>: keeps only members of a union that match U
  • InstanceType<C>: the instance type of a class constructor
  • Uppercase / Lowercase / Capitalize: transform string literal types
type Status = "active" | "banned" | "deleted" | null;
type Visible = Exclude<NonNullable<Status>, "deleted">; // "active" | "banned"
type Event = `on${Capitalize<"click" | "hover">}`;     // "onClick" | "onHover"

const v: Visible = "banned";
const e: Event = "onHover";
console.log(v, e);
banned onHover

Frequently asked questions

What is the difference between Pick and Omit?

Pick creates a type with only the keys you list. Omit creates a type with every key except the ones you list.

How do I make all properties optional in TypeScript?

Wrap the type in Partial, for example Partial<User>. Note that it only applies one level deep.

How do I get the return type of a function?

Use ReturnType<typeof myFunction>. For async functions, wrap it in Awaited to get the resolved value type.