Utility Types
Built-in type transformations
Introduction
In this lesson, you'll learn about utility types in TypeScript. Coming from JavaScript, you already have a foundation for understanding this concept. We'll build on that knowledge while highlighting the key differences.
In JavaScript, you're familiar with built-in type transformations.
TypeScript has its own approach to built-in type transformations, which we'll explore step by step.
The TypeScript Way
Let's see how TypeScript handles this concept. Here's a typical example:
// TypeScript utility types
interface User {
name: string;
age: number;
email: string;
}
// Partial<T> makes all properties optional
function updateUser(user: User, updates: Partial<User>): User {
return { ...user, ...updates };
}
// Pick<T, K> selects specific properties
type UserPreview = Pick<User, "name" | "email">;
// Omit<T, K> excludes specific properties
type UserWithoutEmail = Omit<User, "email">;
// Readonly<T> makes all properties readonly
type ImmutableUser = Readonly<User>;Comparing to JavaScript
Here's how you might have written similar code in JavaScript:
// JavaScript - no built-in type utilities
const user = { name: "Alice", age: 30, email: "a@b.com" };
// Partial updates require careful handling
function updateUser(user, updates) {
return { ...user, ...updates };
}
// No type safety for which properties can be updatedYou may be used to different syntax or behavior.
Partial<T> makes all properties optional
You may be used to different syntax or behavior.
Required<T> makes all properties required
You may be used to different syntax or behavior.
Pick<T, K> selects subset of properties
You may be used to different syntax or behavior.
Omit<T, K> excludes properties
You may be used to different syntax or behavior.
Readonly<T> prevents modification
Step-by-Step Breakdown
1. Partial and Required
Transform required/optional status of all properties.
interface Config {
host: string;
port: number;
debug?: boolean;
}
type PartialConfig = Partial<Config>;
// { host?: string; port?: number; debug?: boolean }
type FullConfig = Required<Config>;
// { host: string; port: number; debug: boolean }2. Pick and Omit
Create new types by selecting or excluding properties.
interface Article {
id: number;
title: string;
content: string;
author: string;
createdAt: Date;
}
type ArticlePreview = Pick<Article, "id" | "title">;
type ArticleInput = Omit<Article, "id" | "createdAt">;3. Record
Create object types with specific key and value types.
// Map of user IDs to users
type UserMap = Record<string, User>;
// Status codes to messages
type StatusMessages = Record<200 | 404 | 500, string>;
const messages: StatusMessages = {
200: "OK",
404: "Not Found",
500: "Server Error"
};Common Mistakes
When coming from JavaScript, developers often make these mistakes:
- Partial<T> makes all properties optional
- Required<T> makes all properties required
- Pick<T, K> selects subset of properties
Key Takeaways
- Utility types transform existing types
- Partial, Required change optionality
- Pick, Omit create subsets
- Record creates mapped types