# Utility Types ## Built-in Utility Types ```typescript // Partial - All properties optional interface User { id: number name: string email: string } type PartialUser = Partial // { id?: number; name?: string; email?: string; } function updateUser(id: number, updates: Partial) { // Only pass fields to update } // Required - All properties required type RequiredUser = Required // { id: number; name: string; email: string; } // Readonly - All properties readonly type ReadonlyUser = Readonly // { readonly id: number; readonly name: string; readonly email: string; } // Pick - Select specific properties type UserSummary = Pick // { id: number; name: string; } // Omit - Exclude specific properties type UserWithoutEmail = Omit // { id: number; name: string; } // Record - Create object type with specific keys type UserRoles = Record // { [key: string]: 'admin' | 'user' | 'guest' } type PageInfo = Record<"home" | "about" | "contact", { title: string }> // { home: { title: string }, about: { title: string }, contact: { title: string } } ``` ## Type Extraction Utilities ```typescript // Extract - Extract types from union type AllTypes = "a" | "b" | "c" | 1 | 2 | 3 type StringTypes = Extract // 'a' | 'b' | 'c' type NumberTypes = Extract // 1 | 2 | 3 // Exclude - Remove types from union type WithoutNumbers = Exclude // 'a' | 'b' | 'c' // NonNullable - Remove null and undefined type MaybeString = string | null | undefined type DefiniteString = NonNullable // string // ReturnType - Extract function return type function getUser() { return { id: 1, name: "John" } } type User = ReturnType // { id: number; name: string } // Parameters - Extract function parameter types function createUser(name: string, age: number) { return { name, age } } type CreateUserParams = Parameters // [string, number] // ConstructorParameters - Extract constructor parameters class Point { constructor( public x: number, public y: number ) {} } type PointParams = ConstructorParameters // [number, number] // InstanceType - Extract instance type from constructor type PointInstance = InstanceType // Point ``` ## Custom Utility Types ```typescript // DeepPartial - Recursive partial type DeepPartial = T extends object ? { [K in keyof T]?: DeepPartial } : T interface Config { database: { host: string port: number credentials: { username: string password: string } } } type PartialConfig = DeepPartial // All nested properties are optional // DeepReadonly - Recursive readonly type DeepReadonly = T extends object ? { readonly [K in keyof T]: DeepReadonly } : T // Mutable - Remove readonly type Mutable = { -readonly [K in keyof T]: T[K] } type MutableUser = Mutable // PickByType - Pick properties by value type type PickByType = { [K in keyof T as T[K] extends U ? K : never]: T[K] } interface Mixed { id: number name: string age: number email: string } type StringProps = PickByType // { name: string; email: string } type NumberProps = PickByType // { id: number; age: number } // OmitByType - Omit properties by value type type OmitByType = { [K in keyof T as T[K] extends U ? never : K]: T[K] } type NoStrings = OmitByType // { id: number; age: number } ``` ## Function Utilities ```typescript // Promisify - Convert sync to async type Promisify any> = ( ...args: Parameters ) => Promise> function syncFunction(x: number): string { return x.toString() } type AsyncVersion = Promisify // (x: number) => Promise // Awaited - Unwrap promise type type AwaitedString = Awaited> // string type DeepAwaited = Awaited>> // number // ThisParameterType - Extract this parameter function greet(this: User, message: string) { return `${this.name}: ${message}` } type ThisType = ThisParameterType // User // OmitThisParameter - Remove this parameter type GreetFunction = OmitThisParameter // (message: string) => string ``` ## Advanced Custom Utilities ```typescript // Nullable - Add null and undefined type Nullable = T | null | undefined // ValueOf - Get union of all property values type ValueOf = T[keyof T] interface Codes { success: 200 notFound: 404 error: 500 } type StatusCode = ValueOf // 200 | 404 | 500 // RequireAtLeastOne - Require at least one property type RequireAtLeastOne = Pick> & { [K in Keys]-?: Required> & Partial>> }[Keys] interface Options { id?: number name?: string email?: string } type AtLeastOne = RequireAtLeastOne // Must have at least one of id, name, or email // RequireOnlyOne - Require exactly one property type RequireOnlyOne = Pick> & { [K in Keys]-?: Required> & Partial, undefined>> }[Keys] type OnlyOne = RequireOnlyOne // Must have exactly one of id, name, or email // Merge - Deep merge two types type Merge = Omit & U interface Base { id: number name: string } interface Extension { name: string // Override email: string // Add } type Combined = Merge // { id: number; name: string; email: string } // ConditionalKeys - Get keys matching condition type ConditionalKeys = { [K in keyof T]: T[K] extends Condition ? K : never }[keyof T] type FunctionKeys = ConditionalKeys // 'abs' | 'acos' | 'sin' | ... ``` ## Tuple Utilities ```typescript // First - Get first element type type First = T extends [infer F, ...any[]] ? F : never type FirstType = First<[string, number, boolean]> // string // Last - Get last element type type Last = T extends [...any[], infer L] ? L : never type LastType = Last<[string, number, boolean]> // boolean // Tail - Remove first element type Tail = T extends [any, ...infer Rest] ? Rest : never type TailTypes = Tail<[string, number, boolean]> // [number, boolean] // Prepend - Add element to beginning type Prepend = [U, ...T] type WithString = Prepend<[number, boolean], string> // [string, number, boolean] // Reverse - Reverse tuple type Reverse = T extends [infer First, ...infer Rest] ? [...Reverse, First] : [] type Reversed = Reverse<[1, 2, 3]> // [3, 2, 1] ``` ## String Utilities ```typescript // Split - Split string into tuple type Split = S extends `${infer T}${D}${infer U}` ? [T, ...Split] : [S] type Parts = Split<"a-b-c", "-"> // ['a', 'b', 'c'] // Join - Join tuple into string type Join = T extends [ infer F extends string, ...infer R extends string[], ] ? R extends [] ? F : `${F}${D}${Join}` : "" type Joined = Join<["a", "b", "c"], "-"> // 'a-b-c' // Replace - Replace substring type Replace< S extends string, From extends string, To extends string, > = S extends `${infer L}${From}${infer R}` ? `${L}${To}${R}` : S type Replaced = Replace<"hello world", "world", "TypeScript"> // 'hello TypeScript' // TrimLeft - Remove leading whitespace type TrimLeft = S extends ` ${infer Rest}` ? TrimLeft : S type Trimmed = TrimLeft<" hello"> // 'hello' ``` ## Quick Reference | Utility | Purpose | | ---------------- | ------------------------------ | | `Partial` | Make all properties optional | | `Required` | Make all properties required | | `Readonly` | Make all properties readonly | | `Pick` | Select subset of properties | | `Omit` | Remove subset of properties | | `Record` | Create object type with keys K | | `Extract` | Extract types assignable to U | | `Exclude` | Remove types assignable to U | | `NonNullable` | Remove null and undefined | | `ReturnType` | Extract function return type | | `Parameters` | Extract function parameters | | `Awaited` | Unwrap Promise type |