TypeScript Utility Types
Essential built-in utility types that make working with TypeScript more efficient
Introduction
TypeScript provides a rich set of built-in utility types that help you transform and manipulate existing types. These utilities are part of the standard library and require no additional imports.
Core Utility Types
Partial
Makes all properties of a type optional.
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;
// { id?: number; name?: string; email?: string; }
// Perfect for update functions
function updateUser(id: number, updates: Partial<User>) {
// ...
}
Required
Makes all properties of a type required.
interface Settings {
theme?: 'light' | 'dark';
notifications?: boolean;
}
type RequiredSettings = Required<Settings>;
// { theme: 'light' | 'dark'; notifications: boolean; }
Readonly
Makes all properties of a type readonly.
interface Config {
apiUrl: string;
timeout: number;
}
type ReadonlyConfig = Readonly<Config>;
// Cannot be modified after creation
Record<K, T>
Creates a type with a set of properties K of type T.
type RolePermissions = Record<'admin' | 'user' | 'guest', string[]>;
// {
// admin: string[];
// user: string[];
// guest: string[];
// }
Pick<T, K>
Picks a subset of properties K from type T.
interface User {
id: number;
name: string;
email: string;
password: string;
}
type PublicUser = Pick<User, 'id' | 'name'>;
// { id: number; name: string; }
Omit<T, K>
Omits a subset of properties K from type T.
type UserWithoutPassword = Omit<User, 'password'>;
// { id: number; name: string; email: string; }
Exclude<T, U>
Excludes types U from union type T.
type Status = 'pending' | 'loading' | 'success' | 'error';
type SuccessStatus = Exclude<Status, 'error'>;
// 'pending' | 'loading' | 'success'
Extract<T, U>
Extracts types U from union type T.
type Status = 'pending' | 'loading' | 'success' | 'error';
type ErrorStatus = Extract<Status, 'error'>;
// 'error'
NonNullable
Excludes null and undefined from type T.
type MaybeString = string | null | undefined;
type DefinitelyString = NonNullable<MaybeString>;
// string
ReturnType
Gets the return type of a function type.
function getUser() {
return { id: 1, name: 'John' };
}
type User = ReturnType<typeof getUser>;
// { id: number; name: string; }
Parameters
Gets the parameter types of a function.
function greet(name: string, age: number) {
// ...
}
type GreetParams = Parameters<typeof greet>;
// [name: string, age: number]
InstanceType
Gets the instance type of a constructor function.
class User {
constructor(public name: string) {}
}
type UserType = InstanceType<typeof User>;
// User
Practical Examples
API Response Handling
interface ApiResponse<T> {
data: T;
status: number;
message: string;
}
type UserData = { id: number; name: string };
type UserResponse = ApiResponse<UserData>;
// Extract just the data type
type User = ApiResponse<UserData>['data'];
Form State Management
interface FormData {
email: string;
password: string;
confirmPassword: string;
}
// Initial form state - all fields optional
type FormState = Partial<FormData>;
// Submitted form - errors for each field
type FormErrors = Record<keyof FormData, string | null>;
Configuration Objects
interface AppConfig {
apiUrl: string;
timeout: number;
retries: number;
debug: boolean;
}
// Environment-specific overrides
type EnvConfig = Partial<AppConfig>;
// Required production config
type ProductionConfig = Required<Pick<AppConfig, 'apiUrl' | 'timeout'>>;
Advanced Patterns
Combining Utilities
type ReadonlyPartial<T> = Readonly<Partial<T>>;
type Config = ReadonlyPartial<AppConfig>;
Conditional Utility
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
type WritableUser = Mutable<ReadonlyUser>;
When to Use Utility Types
✅ Good use cases:
- API response transformations
- Form state management
- Test data generation
- Creating variations of existing types
❌ Avoid when:
- The type becomes unreadable
- You're creating overly complex abstractions
- Simple interfaces would work better
Conclusion
Utility types are powerful tools in your TypeScript toolkit. Master them to write more flexible, maintainable type definitions.
#typescript #types #programming