20 minlesson

Built-in Utility Types

Built-in Utility Types

TypeScript provides utility types that transform existing types. These are essential for flexible APIs and pattern implementations.

Partial

Makes all properties optional:

typescript
1interface Shipment {
2 id: string;
3 origin: Address;
4 destination: Address;
5 weight: number;
6 status: string;
7}
8
9// All properties become optional
10type ShipmentUpdate = Partial<Shipment>;
11
12// Equivalent to:
13// {
14// id?: string;
15// origin?: Address;
16// destination?: Address;
17// weight?: number;
18// status?: string;
19// }
20
21function updateShipment(id: string, updates: Partial<Shipment>): Shipment {
22 const current = getShipment(id);
23 return { ...current, ...updates };
24}
25
26// Only update what's needed
27updateShipment('SHP001', { status: 'delivered' });
28updateShipment('SHP002', { weight: 15, status: 'in_transit' });

Required

Makes all properties required (opposite of Partial):

typescript
1interface Config {
2 apiKey?: string;
3 timeout?: number;
4 retries?: number;
5}
6
7// All properties become required
8type RequiredConfig = Required<Config>;
9
10function initializeClient(config: RequiredConfig): Client {
11 // All properties guaranteed to exist
12 console.log(config.apiKey); // string, not string | undefined
13 console.log(config.timeout); // number, not number | undefined
14}

Pick<T, Keys>

Select specific properties:

typescript
1interface Package {
2 id: string;
3 weight: number;
4 dimensions: Dimensions;
5 fragile: boolean;
6 value: number;
7 description: string;
8}
9
10// Only these properties
11type PackageSummary = Pick<Package, 'id' | 'weight' | 'description'>;
12
13// Equivalent to:
14// {
15// id: string;
16// weight: number;
17// description: string;
18// }
19
20function displaySummary(pkg: PackageSummary): void {
21 console.log(`${pkg.id}: ${pkg.description} (${pkg.weight}kg)`);
22}

Omit<T, Keys>

Exclude specific properties:

typescript
1interface User {
2 id: string;
3 email: string;
4 password: string;
5 name: string;
6 role: string;
7}
8
9// Everything except password
10type PublicUser = Omit<User, 'password'>;
11
12// Exclude multiple
13type UserPreview = Omit<User, 'password' | 'email'>;
14
15function getPublicProfile(user: User): PublicUser {
16 const { password, ...publicData } = user;
17 return publicData;
18}

Record<Keys, Type>

Create an object type with specific keys and value type:

typescript
1// All carriers have Rate type
2type Carrier = 'usps' | 'fedex' | 'ups';
3
4interface Rate {
5 base: number;
6 perKg: number;
7}
8
9type CarrierRates = Record<Carrier, Rate>;
10
11const rates: CarrierRates = {
12 usps: { base: 5.99, perKg: 0.50 },
13 fedex: { base: 8.99, perKg: 0.75 },
14 ups: { base: 7.99, perKg: 0.65 }
15};
16
17// Dynamic keys
18type StatusCounts = Record<string, number>;
19
20const counts: StatusCounts = {
21 pending: 10,
22 shipped: 25,
23 delivered: 100
24};

Readonly

Makes all properties readonly:

typescript
1interface Order {
2 id: string;
3 items: string[];
4 total: number;
5}
6
7type ImmutableOrder = Readonly<Order>;
8
9const order: ImmutableOrder = {
10 id: 'ORD001',
11 items: ['item1', 'item2'],
12 total: 99.99
13};
14
15// order.id = 'new-id'; // Error: readonly
16// order.total = 50; // Error: readonly
17// order.items.push('item3'); // Still works! Only shallow readonly

ReturnType

Extract return type of a function:

typescript
1function calculateShipping(weight: number, zone: string): {
2 rate: number;
3 estimatedDays: number;
4 carrier: string;
5} {
6 // Implementation
7 return { rate: 25, estimatedDays: 3, carrier: 'fedex' };
8}
9
10// Extract the return type
11type ShippingResult = ReturnType<typeof calculateShipping>;
12
13// Now we can use it elsewhere
14function processResult(result: ShippingResult): void {
15 console.log(`${result.carrier}: $${result.rate}`);
16}

Parameters

Extract parameter types as tuple:

typescript
1function createShipment(
2 origin: Address,
3 destination: Address,
4 weight: number,
5 options?: ShippingOptions
6): Shipment {
7 // Implementation
8}
9
10type CreateShipmentParams = Parameters<typeof createShipment>;
11// [Address, Address, number, ShippingOptions?]
12
13// Useful for wrapper functions
14function createShipmentWithLogging(...args: CreateShipmentParams): Shipment {
15 console.log('Creating shipment:', args[0], '->', args[1]);
16 return createShipment(...args);
17}

NonNullable

Removes null and undefined:

typescript
1type MaybeAddress = Address | null | undefined;
2
3type DefiniteAddress = NonNullable<MaybeAddress>;
4// Address (null and undefined removed)
5
6function requireAddress(addr: MaybeAddress): DefiniteAddress {
7 if (!addr) {
8 throw new Error('Address required');
9 }
10 return addr; // Now it's NonNullable
11}

Exclude<T, U> and Extract<T, U>

Filter union types:

typescript
1type Status = 'pending' | 'processing' | 'shipped' | 'delivered' | 'cancelled';
2
3// Remove specific values
4type ActiveStatus = Exclude<Status, 'cancelled' | 'delivered'>;
5// 'pending' | 'processing' | 'shipped'
6
7// Keep only specific values
8type FinalStatus = Extract<Status, 'delivered' | 'cancelled'>;
9// 'delivered' | 'cancelled'

Combining Utility Types

Utility types compose well:

typescript
1interface Shipment {
2 id: string;
3 origin: Address;
4 destination: Address;
5 weight: number;
6 status: Status;
7 createdAt: Date;
8 updatedAt: Date;
9}
10
11// Partial update excluding id and timestamps
12type ShipmentUpdate = Partial<Omit<Shipment, 'id' | 'createdAt'>>;
13
14// Required fields for creation (no id yet)
15type CreateShipmentInput = Required<Omit<Shipment, 'id' | 'createdAt' | 'updatedAt'>>;
16
17// Readonly summary
18type ShipmentSnapshot = Readonly<Pick<Shipment, 'id' | 'status' | 'createdAt'>>;

Summary

UtilityPurposeCommon Use
Partial<T>All optionalUpdate/patch operations
Required<T>All requiredStrict config validation
Pick<T, K>Select propertiesDTOs, summaries
Omit<T, K>Exclude propertiesRemove sensitive data
Record<K, T>Key-value mappingLookup tables
Readonly<T>ImmutableState snapshots
ReturnType<T>Function returnType inference
Parameters<T>Function paramsWrapper functions
NonNullable<T>Remove null/undefinedValidation
Exclude<T, U>Filter out typesNarrow unions
Extract<T, U>Keep typesFilter unions

Next: Create custom mapped and conditional types!

Built-in Utility Types - Anko Academy