TypeScript Utility Types | Partial, Pick, Omit, Record & Built-ins
이 글의 핵심
A practical tour of TypeScript’s built-in utility types: how they transform types, how they are implemented with mapped types, and how to use them in real APIs and UI state.
Introduction
Utility types are type transformation tools that TypeScript provides out of the box.
1. Partial
Concept
Makes every property optional.
interface User {
id: string;
name: string;
email: string;
age: number;
}
type PartialUser = Partial<User>;
// {
// id?: string;
// name?: string;
// email?: string;
// age?: number;
// }
Real-world example
function updateUser(id: string, updates: Partial<User>): User {
const user = getUser(id);
return { ...user, ...updates };
}
updateUser("U001", { name: "김철수" });
updateUser("U002", { email: "[email protected]", age: 30 });
How it works
type MyPartial<T> = {
[K in keyof T]?: T[K];
};
2. Required
Concept
Makes every property required.
interface User {
id: string;
name: string;
email?: string;
age?: number;
}
type RequiredUser = Required<User>;
// {
// id: string;
// name: string;
// email: string;
// age: number;
// }
How it works
type MyRequired<T> = {
[K in keyof T]-?: T[K];
};
3. Readonly
Concept
Makes every property read-only.
interface User {
id: string;
name: string;
email: string;
}
type ReadonlyUser = Readonly<User>;
const user: ReadonlyUser = {
id: "U001",
name: "홍길동",
email: "[email protected]"
};
// user.name = "김철수"; // ❌ Error
How it works
type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};
4. Pick<T, K>
Concept
Selects only certain properties.
interface User {
id: string;
name: string;
email: string;
age: number;
address: string;
}
type UserPreview = Pick<User, "id" | "name">;
// {
// id: string;
// name: string;
// }
const preview: UserPreview = {
id: "U001",
name: "홍길동"
};
Real-world example
type LoginForm = Pick<User, "email">;
type SignupForm = Pick<User, "name" | "email" | "age">;
How it works
type MyPick<T, K extends keyof T> = {
[P in K]: T[P];
};
5. Omit<T, K>
Concept
Removes specific properties.
interface User {
id: string;
name: string;
email: string;
password: string;
}
type UserWithoutPassword = Omit<User, "password">;
// {
// id: string;
// name: string;
// email: string;
// }
const user: UserWithoutPassword = {
id: "U001",
name: "홍길동",
email: "[email protected]"
};
Real-world example
type UserResponse = Omit<User, "password">;
type CreateUserRequest = Omit<User, "id">;
How it works
type MyOmit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
6. Record<K, T>
Concept
Builds an object type with fixed keys and a given value type.
type Role = "admin" | "user" | "guest";
type Permissions = Record<Role, string[]>;
const permissions: Permissions = {
admin: ["read", "write", "delete"],
user: ["read", "write"],
guest: ["read"]
};
Real-world example
type ErrorCode = "NOT_FOUND" | "UNAUTHORIZED" | "SERVER_ERROR";
type ErrorMessages = Record<ErrorCode, string>;
const errors: ErrorMessages = {
NOT_FOUND: "리소스를 찾을 수 없습니다",
UNAUTHORIZED: "인증이 필요합니다",
SERVER_ERROR: "서버 에러가 발생했습니다"
};
type Language = "ko" | "en" | "ja";
type Translations = Record<Language, Record<string, string>>;
const translations: Translations = {
ko: { greeting: "안녕하세요", goodbye: "안녕히 가세요" },
en: { greeting: "Hello", goodbye: "Goodbye" },
ja: { greeting: "こんにちは", goodbye: "さようなら" }
};
How it works
type MyRecord<K extends keyof any, T> = {
[P in K]: T;
};
7. Exclude<T, U>
Concept
Removes types from a union.
type AllRoles = "admin" | "user" | "guest" | "moderator";
type NonAdminRoles = Exclude<AllRoles, "admin">;
// "user" | "guest" | "moderator"
let role: NonAdminRoles = "user";
8. Extract<T, U>
Concept
Extracts only the members of a union that are assignable to U.
type AllRoles = "admin" | "user" | "guest" | "moderator";
type AdminRoles = Extract<AllRoles, "admin" | "moderator">;
// "admin" | "moderator"
let role: AdminRoles = "admin";
9. NonNullable
Concept
Removes null and undefined from a type.
type MaybeString = string | null | undefined;
type DefiniteString = NonNullable<MaybeString>;
// string
let value: DefiniteString = "hello";
10. ReturnType
Concept
Extracts a function’s return type.
function getUser() {
return {
id: "U001",
name: "홍길동",
email: "[email protected]"
};
}
type User = ReturnType<typeof getUser>;
11. Parameters
Concept
Extracts a function’s parameter types as a tuple.
function createUser(name: string, age: number, email: string) {
return { name, age, email };
}
type CreateUserParams = Parameters<typeof createUser>;
// [string, number, string]
const params: CreateUserParams = ["홍길동", 25, "[email protected]"];
createUser(...params);
12. Practical examples
Example 1: API typing
interface User {
id: string;
name: string;
email: string;
password: string;
createdAt: Date;
updatedAt: Date;
}
type CreateUserRequest = Omit<User, "id" | "createdAt" | "updatedAt">;
type UpdateUserRequest = Partial<Omit<User, "id" | "createdAt" | "updatedAt">>;
type UserResponse = Omit<User, "password">;
type UserListItem = Pick<User, "id" | "name" | "email">;
Example 2: Form state
interface FormField<T> {
value: T;
error: string | null;
touched: boolean;
}
type FormState<T> = {
[K in keyof T]: FormField<T[K]>;
};
interface LoginData {
email: string;
password: string;
}
type LoginFormState = FormState<LoginData>;
const form: LoginFormState = {
email: { value: "", error: null, touched: false },
password: { value: "", error: null, touched: false }
};
Example 3: App state slices
interface AppState {
user: User | null;
posts: Post[];
loading: boolean;
error: string | null;
}
type LoadingState = Pick<AppState, "loading">;
type ErrorState = Pick<AppState, "error">;
type DataState = Omit<AppState, "loading" | "error">;
Summary
Takeaways
- Partial: all properties optional
- Required: all properties required
- Readonly: all properties read-only
- Pick: select properties
- Omit: remove properties
- Record: key–value object types
- Exclude / Extract: filter unions
- ReturnType: function return type
- Parameters: function parameter tuple type
Utility types at a glance
| Type | Use case | Example |
|---|---|---|
| Partial | Optional update payloads | PATCH bodies |
| Required | Ensure completeness | Validated records |
| Pick | Subsets | List rows, previews |
| Omit | Strip secrets | Responses without password |
| Record | Fixed key sets | Roles, error catalogs |