2024-11-30,   κΆŒμˆ˜μ—°

πŸ“ TypeScript μœ ν‹Έλ¦¬ν‹° νƒ€μž…κ³Ό ν™œμš©

TypeScriptλŠ” μœ ν‹Έλ¦¬ν‹° νƒ€μž…(Utility Types)을 μ œκ³΅ν•˜μ—¬ κΈ°μ‘΄ νƒ€μž…μ„ λ³€ν˜•ν•˜κ±°λ‚˜ μƒˆλ‘œμš΄ νƒ€μž…μ„ μ‰½κ²Œ 생성할 수 μžˆλ„λ‘ μ§€μ›ν•©λ‹ˆλ‹€. 특히, Omit, Pick, Partial 같은 νƒ€μž…μ€ λ³΅μž‘ν•œ 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°κ³Ό ν”„λ‘ νŠΈμ—”λ“œ μƒνƒœ 관리 λΌμ΄λΈŒλŸ¬λ¦¬μ—μ„œ 맀우 μœ μš©ν•˜κ²Œ μ“°μž…λ‹ˆλ‹€.




🌟 Omit νƒ€μž… κ°œμš”

Omit은 κΈ°μ‘΄ 객체 νƒ€μž…μ—μ„œ νŠΉμ • 속성을 μ œμ™Έν•œ νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€. λΆˆν•„μš”ν•œ 속성을 μ œκ±°ν•˜κ±°λ‚˜ 일뢀 속성을 μˆ¨κ²¨μ•Ό ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

μ‚¬μš©λ²•

  • T: λ³€ν˜•ν•  원본 νƒ€μž….
  • K: μ œμ™Έν•  μ†μ„±μ˜ ν‚€(Key)λ“€.

Omit은 λ‚΄λΆ€μ μœΌλ‘œ Pickκ³Ό Excludeλ₯Ό μ‚¬μš©ν•˜μ—¬, μ§€μ •λœ 속성을 μ œμ™Έν•œ μƒˆλ‘œμš΄ νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€.



πŸ“œ Omit μ‚¬μš© 예제

기본 예제

interface User {
  id: number;
  name: string;
  email: string;
  password: string;
}

type PublicUser = Omit<User, "password">;

const user: PublicUser = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
};

μ—¬κΈ°μ„œ PublicUserλŠ” User νƒ€μž…μ—μ„œ password μ†μ„±λ§Œ μ œμ™Έν•œ νƒ€μž…μœΌλ‘œ λ§Œλ“€μ–΄μ§‘λ‹ˆλ‹€. 이 방식은 λ―Όκ°ν•œ μ •λ³΄λ‚˜ ν•„μš”ν•˜μ§€ μ•Šμ€ 속성을 μ œμ™Έν•˜λŠ” 데 맀우 μœ μš©ν•©λ‹ˆλ‹€.



πŸ›  TypeScript μœ ν‹Έλ¦¬ν‹° νƒ€μž… ν™•μž₯

Omit 외에도 λ‹€μ–‘ν•œ μœ ν‹Έλ¦¬ν‹° νƒ€μž…λ“€μ΄ μžˆμŠ΅λ‹ˆλ‹€. 이듀을 μ‘°ν•©ν•˜κ±°λ‚˜ λ‹¨λ…μœΌλ‘œ μ‚¬μš©ν•˜λ©΄ λ”μš± κ°•λ ₯ν•œ νƒ€μž… μ‹œμŠ€ν…œμ„ ꡬ좕할 수 μžˆμŠ΅λ‹ˆλ‹€.



1. Pick νƒ€μž…

Pick은 κΈ°μ‘΄ 객체 νƒ€μž…μ—μ„œ νŠΉμ • μ†μ„±λ§Œ μ„ νƒν•˜μ—¬ μƒˆλ‘œμš΄ νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€.

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

μ‚¬μš© 예제

type UserBasicInfo = Pick<User, "id" | "name">;

const userBasic: UserBasicInfo = {
  id: 1,
  name: "Alice",
};

Pick은 UI에 νŠΉμ • λ°μ΄ν„°λ§Œ ν•„μš”ν•œ κ²½μš°λ‚˜ μš”μ²­/μ‘λ‹΅μ˜ 데이터 ν˜•νƒœλ₯Ό μ€„μ΄κ³ μž ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.



2. Partial νƒ€μž…

Partial은 λͺ¨λ“  속성을 선택적(optional)으둜 λ§Œλ“œλŠ” νƒ€μž…μž…λ‹ˆλ‹€. 주둜 μ—…λ°μ΄νŠΈμš© 객체λ₯Ό μ •μ˜ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

type Partial<T> = {
  [P in keyof T]?: T[P];
};

μ‚¬μš© 예제

type UpdateUser = Partial<User>;

const updateUser: UpdateUser = {
  email: "new_email@example.com",
};

Partial은 νŠΉμ • μ†μ„±λ§Œ μ—…λ°μ΄νŠΈκ°€ ν•„μš”ν•œ κ²½μš°μ— ν™œμš©λ©λ‹ˆλ‹€.



3. Required νƒ€μž…

RequiredλŠ” λͺ¨λ“  속성을 ν•„μˆ˜(non-optional)둜 λ§Œλ“œλŠ” νƒ€μž…μž…λ‹ˆλ‹€. 주둜 선택적 속성을 κ°•μ œν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€.

type Required<T> = {
  [P in keyof T]-?: T[P];
};

μ‚¬μš© 예제

type FullUser = Required<Partial<User>>;

const fullUser: FullUser = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  password: "secure",
};

4. Readonly νƒ€μž…

ReadonlyλŠ” λͺ¨λ“  속성을 읽기 μ „μš©μœΌλ‘œ λ§Œλ“€μ–΄, 객체λ₯Ό λΆˆλ³€(Immutable) μƒνƒœλ‘œ μœ μ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

μ‚¬μš© 예제

type ReadonlyUser = Readonly<User>;

const readonlyUser: ReadonlyUser = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  password: "secret",
};

// readonlyUser.name = "Bob"; // Error: 읽기 μ „μš© μ†μ„±μž…λ‹ˆλ‹€.

5. Record νƒ€μž…

RecordλŠ” ν‚€(Key)와 κ°’(Value)의 νƒ€μž…μ„ μ§€μ •ν•˜μ—¬ 객체 νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€.

type Record<K extends keyof any, T> = {
  [P in K]: T;
};

μ‚¬μš© 예제

type PostStatus = "draft" | "published" | "archived";

type PostDirectory = Record<PostStatus, string>;

const postDirectory: PostDirectory = {
  draft: "/drafts",
  published: "/published",
  archived: "/archives",
};

RecordλŠ” λ™μ μœΌλ‘œ ν‚€λ₯Ό 지정해야 ν•˜λŠ” κ²½μš°μ— μ ν•©ν•©λ‹ˆλ‹€.


6. Exclude νƒ€μž…

ExcludeλŠ” 두 νƒ€μž…μ—μ„œ μ œμ™Έν•  νƒ€μž…μ„ λͺ…μ‹œν•˜μ—¬ μƒˆλ‘œμš΄ νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€.

type Exclude<T, U> = T extends U ? never : T;

μ‚¬μš© 예제

type AllActions = "create" | "update" | "delete" | "view";
type AdminActions = Exclude<AllActions, "view">;

const action: AdminActions = "create"; // OK

7. Extract νƒ€μž…

ExtractλŠ” 두 νƒ€μž… κ°„ 곡톡 νƒ€μž…μ„ μΆ”μΆœν•©λ‹ˆλ‹€.

type Extract<T, U> = T extends U ? T : never;

μ‚¬μš© 예제

type CommonActions = Extract<AllActions, "create" | "view">;

const action: CommonActions = "create"; // OK

8. NonNullable νƒ€μž…

NonNullableλŠ” nullκ³Ό undefinedλ₯Ό μ œκ±°ν•œ νƒ€μž…μ„ μƒμ„±ν•©λ‹ˆλ‹€.

type NonNullable<T> = T extends null | undefined ? never : T;

μ‚¬μš© 예제

type Name = string | null | undefined;
type DefinedName = NonNullable<Name>;

const name: DefinedName = "Alice"; // OK

πŸ”„ μœ ν‹Έλ¦¬ν‹° νƒ€μž… μ‘°ν•©

TypeScript μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ€ μ‘°ν•©ν•˜μ—¬ λ”μš± κ°•λ ₯ν•œ νƒ€μž…μ„ λ§Œλ“€ 수 μžˆμŠ΅λ‹ˆλ‹€.

예제: API 응닡 처리

type ApiResponse<T> = Partial<Readonly<T>>;

type UserResponse = ApiResponse<Omit<User, "password">>;

const response: UserResponse = {
  id: 1,
  name: "Alice",
};

이 μ½”λ“œλŠ” API μ‘λ‹΅μ—μ„œ λΉ„λ°€λ²ˆν˜Έλ₯Ό μ œμ™Έν•˜κ³  읽기 μ „μš© 및 선택적 속성을 μΆ”κ°€ν•©λ‹ˆλ‹€.


πŸ“š κ²°λ‘ 

TypeScript의 μœ ν‹Έλ¦¬ν‹° νƒ€μž…μ€ λ³΅μž‘ν•œ νƒ€μž… μ •μ˜λ₯Ό κ°„κ²°ν•˜κ²Œ λ§Œλ“€κ³ , λ°˜λ³΅λ˜λŠ” μ½”λ“œ μž‘μ„±μ˜ 뢀담을 μ€„μ—¬μ€λ‹ˆλ‹€. Omit, Pick, Partial 같은 νƒ€μž…μ„ 적절히 ν™œμš©ν•˜λ©΄ μœ μ—°ν•˜κ³  μœ μ§€λ³΄μˆ˜ κ°€λŠ₯ν•œ μ½”λ“œ μž‘μ„±μ΄ κ°€λŠ₯ν•˜λ©°, λ”μš± κ°•λ ₯ν•œ νƒ€μž… μ‹œμŠ€ν…œμ„ ꡬ좕할 수 μžˆμŠ΅λ‹ˆλ‹€.

μ°Έκ³ 


μ—…λ°μ΄νŠΈ: