Utility types are built-in TypeScript helpers that transform existing types into new types. They help you avoid repeating similar object shapes again and again.
For example, a user record may have many required fields in the database, but an update form may allow only a few fields to be changed. Instead of writing a second almost-identical type by hand, you can derive it with a utility type.
type User = {
id: number;
name: string;
email: string;
active: boolean;
};
type UserUpdate = Partial<User>;
type UserPreview = Pick<User, "id" | "name">;
const patch: UserUpdate = { active: false };
const preview: UserPreview = { id: 1, name: "Admin" };
Partial<T> makes every property optional. This is useful for patch/update payloads where a caller sends only the fields that changed.
Required<T> does the opposite: it makes every property required. This can be useful after validation, when a previously optional configuration object has been normalized into a complete object.
type Profile = {
name: string;
bio?: string;
avatarUrl?: string;
};
type ProfilePatch = Partial<Profile>;
type CompleteProfile = Required<Profile>;
const updateProfile = (id: number, patch: ProfilePatch) => {
console.log("Updating", id, patch);
};
const complete: CompleteProfile = {
name: "Asha",
bio: "Frontend developer",
avatarUrl: "/images/asha.png",
};
updateProfile(1, { bio: "TypeScript learner" });
Pick<T, K> creates a type with only selected properties from another type. It is helpful when a screen, component, or API response should expose a smaller version of a larger model.
Omit<T, K> removes selected properties. It is useful when a type is mostly correct but contains fields that should not be visible, editable, or accepted from a client.
type Product = {
id: number;
name: string;
price: number;
internalCost: number;
createdAt: string;
};
type ProductCard = Pick<Product, "id" | "name" | "price">;
type PublicProduct = Omit<Product, "internalCost">;
const card: ProductCard = {
id: 10,
name: "Keyboard",
price: 1499,
};
const product: PublicProduct = {
id: 10,
name: "Keyboard",
price: 1499,
createdAt: "2026-05-24",
};
Record<K, V> creates an object type where the keys have type K and the values have type V. It is commonly used for dictionaries, lookup tables, feature flags, translations, and grouped data.
Use Record when the object is used like a map. If every property has a different meaning, a normal object type is usually clearer.
type FeatureName = "darkMode" | "betaDashboard" | "newEditor";
type FeatureFlags = Record<FeatureName, boolean>;
const flags: FeatureFlags = {
darkMode: true,
betaDashboard: false,
newEditor: true,
};
type ErrorMessages = Record<number, string>;
const messages: ErrorMessages = {
400: "Bad request",
401: "Login required",
500: "Server error",
};
Readonly<T> makes all properties read-only at the type level. It is useful when a value should be treated as immutable after creation, such as configuration, constants, or values passed into pure functions.
Readonly does not deeply freeze nested objects at runtime. It is a TypeScript-level protection for the properties of that type.
type AppConfig = {
appName: string;
apiBaseUrl: string;
retries: number;
};
const config: Readonly<AppConfig> = {
appName: "Tutorials Logic",
apiBaseUrl: "https://api.example.com",
retries: 3,
};
// config.retries = 5;
// Error: retries is read-only.
Some utility types inspect functions. ReturnType<T> gets the return type of a function. Parameters<T> gets a tuple of parameter types. These are useful when you want helper code to stay connected to an existing function signature.
Awaited<T> unwraps a promise-like type. It is helpful when working with async service functions because you can describe the resolved value without manually copying the type.
async function fetchUser(id: number) {
return {
id,
name: "Admin",
active: true,
};
}
type FetchUserArgs = Parameters<typeof fetchUser>;
type FetchUserPromise = ReturnType<typeof fetchUser>;
type LoadedUser = Awaited<FetchUserPromise>;
const args: FetchUserArgs = [1];
const user: LoadedUser = {
id: 1,
name: "Admin",
active: true,
};
| Utility | Purpose | Common Use |
|---|---|---|
Partial<T> | Make all properties optional | Patch/update payloads |
Required<T> | Make all properties required | Validated configuration |
Pick<T, K> | Select specific properties | Preview cards and small DTOs |
Omit<T, K> | Remove specific properties | Public models without private fields |
Readonly<T> | Prevent property assignment | Configuration and immutable inputs |
Record<K, V> | Create a typed key-value object | Dictionaries and lookups |
ReturnType<T> | Extract a function return type | Helper types based on services |
Awaited<T> | Get resolved Promise value | Async data types |
Partial and Required change whether properties are optional.
Pick and Omit create focused versions of larger models.
Record is best for typed dictionaries and lookup objects.
Explore 500+ free tutorials across 20+ languages and frameworks.