본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 27. 07:10

아무도 가르쳐주지 않지만 반드시 알아야 할 TypeScript 유틸리티 타입 (Utility Types)

요약

TypeScript의 기본 유틸리티 타입을 넘어 실무에서 보일러플레이트 코드를 줄여주는 핵심 유틸리티 타입들을 소개합니다. Omit, Record, ReturnType 등 실제 프로젝트 경험을 바탕으로 한 활용 팁을 제공합니다.

핵심 포인트

  • Omit을 활용한 효율적인 타입 필드 제거
  • Record를 이용한 타입 안전한 딕셔너리 구현
  • ReturnType과 Parameters를 통한 함수 시그니처 역공학
  • InstanceType 및 ConstructorParameters를 활용한 클래스 타입 추출
  • 문자열 리터럴 타입 변환 유틸리티 활용

아무도 가르쳐주지 않지만 반드시 알아야 할 TypeScript 유틸리티 타입 (Utility Types)

모든 TypeScript 튜토리얼은 Partial, Required, 그리고 Pick을 다룹니다. 하지만 TypeScript에는 수 시간의 보일러플레이트 (Boilerplate) 코드를 줄여줄 수 있는 유틸리티 타입 (Utility Types) 도구 모음이 가득하며, 대부분의 개발자는 이를 배우지 못합니다.

4개의 프로젝트에서 3년 동안 매일 TypeScript를 사용하며, 제가 실제로 사용하는 유틸리티 타입들을 소개합니다.

1. OmitPick의 역(Inverse)

Pick이 필드를 유지한다는 것을 알고 계실 겁니다. Omit은 필드를 제거합니다. 이것은 제가 가장 자주 사용하는 타입입니다.

interface User {
  id: string;
  name: string;
...

프로 팁 (Pro tip): 체이닝 (Chain) 하세요. Omit<User, 'id' | 'createdAt' | 'password'>는 처음부터 타입을 새로 만드는 것보다 훨씬 깔끔합니다.

2. Record — 타입 안전한 딕셔너리 (Type-Safe Dictionaries)

{ [key: string]: T } 사용을 멈추세요. Record가 더 깔끔하며 의도가 명확합니다.

// 나쁜 예 (하지만 흔함)
const statusMap: { [key: string]: number } = {
  pending: 0,
...

상태 값을 잊어버리면 TypeScript가 컴파일 타임 (Compile time)에 이를 잡아냅니다. 더 이상 undefined로 인한 깜짝 놀랄 일은 없습니다.

3. ReturnTypeParameters — 함수 시그니처 (Function Signatures) 역공학

때로는 필요한 타입이 여러분이 작성하지 않은 함수 안에 이미 숨겨져 있을 때가 있습니다.

// 라이브러리를 사용 중이며 응답(response)의 타입을 지정하고 싶을 때
const fetchUser = async (id: string) => {
  const res = await api.get(`/users/${id}`);
...

이것은 내보내진(exported) 타입을 직접 제어할 수 없는 서드파티 라이브러리 (Third-party libraries)를 사용할 때 특히 강력합니다.

4. ConstructorParameters — 타입 팩토리 함수 (Type Factory Functions)

class Database {
  constructor(url: string, options: { poolSize: number }) {}
  query(sql: string) { /* ... */ }
...

5. InstanceType — 클래스 생성자 (Class Constructors)에서 추출

class ErrorWithCode extends Error {
  constructor(public code: number, message: string) { super(message); }
}
...

이것은 제네릭 팩토리 패턴 (Generic factory patterns)이나 의존성 주입 (Dependency injection)을 다룰 때 중요합니다.

6. Uppercase, Lowercase, Capitalize, Uncapitalize — 문자열 리터럴 타입 (String Literal Types)

TypeScript 4.1에서 이 기능들이 추가되었습니다. API 설계 시 묘하게 유용합니다.

type HttpMethod = 'get' | 'post' | 'put' | 'delete';

// 대문자로 정규화 (Normalize to uppercase)
...

7. 더 일찍 알았더라면 좋았을 것: Awaited

TypeScript 4.5에서 Awaited가 추가되었습니다. 이는 Promise 타입을 재귀적으로 언래핑 (Unwrap) 합니다.

type T1 = Awaited<Promise<string>>;
// string

...

내가 따르는 패턴

어떤 유틸리티 타입 (Utility Type)을 사용해야 할지에 대한 나의 사고 모델은 다음과 같습니다:

필요 사항유틸리티 타입 (Utility Type)
필드 제거Omit
...

이것이 중요한 이유

이것들은 단순한 지름길이 아닙니다. 이것들은 **단일 진실 공급원 (Single Sources of Truth)**을 생성합니다. User 인터페이스 (Interface)가 변경되면, 파생된 모든 타입이 자동으로 업데이트됩니다. 수동 동기화도, 불일치 (Drift)도 발생하지 않습니다.

Omit<User, 'password'>를 작성하는 개발자는, 인터페이스를 수동으로 다시 만들었다가 User에 새로운 필드가 추가되었을 때 업데이트를 잊어버리는 개발자보다 버그를 훨씬 적게 겪을 것입니다.

여러분은 매일 어떤 유틸리티 타입을 사용하시나요? 뒤늦게 발견해서 첫날부터 알았더라면 좋았을 것 같은 타입은 무엇인가요?

댓글로 공유해 주세요 — 함께 궁극의 TypeScript 유틸리티 타입 치트 시트 (Cheat Sheet)를 만들어 봅시다.

📖 더 많은 개발자 인사이트와 튜토리얼을 codcompass.com에서 확인하세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0