본문으로 건너뛰기
yceffort
PostsSeriesTagsAbout🧪 Research
EN

Tweaks

theme
accent palette
film grain
minimal mode
BACK TO INDEX
◆ ESSAY
--min
--year
KOoriginal

mailMail icongithubtwitter
yceffort
•
© 2026
•
https://yceffort.kr
BACK TO INDEX
◆ ESSAY

타입스크립트의 Omit은 어떻게 동작할까? Exclude, Pick 부터 알아보기

avatar
yceffort
2022-03-16 · 4분
4min
2022year
KOoriginal
typescript

Table of Contents

  • exclude
    • extends
  • pick
  • Omit
    • Omit 과정 다시한번 살펴보기

exclude

exclude는 여러개의 타입이 함께 존재하는 유니언 타입에서 특정 타입을 제거하는 유틸리티 타입이다. exclude로 제거할 수 있는 것은 하나의 타입 부터 유니언 까지 가능하다.

type T0 = Exclude<'a' | 'b' | 'c', 'a'>
// type T0 = "b" | "c"
type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>
// type T1 = "c"
type T2 = Exclude<string | number | (() => void), Function>
// type T2 = string | number

exclude의 동작방식을 보면 다음과 같이 확인할 수 있다.

/**
 * Exclude from T those types that are assignable to U
 */
type Exclude<T, U> = T extends U ? never : T

extends

제네릭에서 사용되는 T extends U라는 키워드는 T가 U라는 타입인지 를 의미한다.

즉, 위 예시를 해석하면 다음과 같다.

T가 U의 타입 이라면, never (빈 타입)을, 그렇지 않다면 T 그자체, 즉 원래대로 돌려준다

pick

pick은 객체 타입에서, 넘겨받은 키에 해당하는 키만 리턴하는 새로운 객체 타입을 만들어준다.

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = Pick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
}

pick이 작동하기 위해서는, 먼저 객체에서 키를 뽑아서 해당 키를 제외해야 하므로, 객체 타입에서 키를 뽑는 법 부터 알아야 한다.

keyof Todo // "title" | "description" | "completed" | "createdAt"

그 다음, 이 키에 해당 하는 객체 타입의 값만 뽑아 오면 될 것이다.

type Pick<T, Key extends keyof T> = {
  [NewKey in key]: T[key]
}

작동방식을 확인하면 거의 유사하다는 것을 알 수 있다.

타입스크립트 원본 코드 확인해보기

Omit

omit 은 객체 타입 (interface 등)에서 특정 키를 기준으로 생략하여 타입을 내려주는 유틸리티 타입이다.

interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: number
}

// description을 제외
type TodoPreview = Omit<Todo, 'description'>

const todo: TodoPreview = {
  title: 'Clean room',
  completed: false,
  createdAt: 1615544252770,
}

마찬가지로 키를 먼저 뽑아온다.

type TodoKeys = keyof Todo // "title" | "description" | "completed" | "createdAt"

그리고 이번에는 해당하는 값을 가져오는 것이 아니고, 제거를 해야한다. 여기서 부터 조금씩 복잡해지는데, 하나씩 해보자.

먼저 앞서 사용했던 Pick과 Exclude를 활용하여, TODO에서 title만 제거해보자.

type TodoWithoutTitle = Pick<Todo, Exclude<keyof Todo, 'title'>>
// type TodoWithoutTitle = {
//     description: string;
//     completed: boolean;
//     createdAt: number;
// }

이를 깔끔하게 제네릭으로 정리하면 다음과 같다.

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

객체의 키로 string, number, symbol만 가능하기 때문에, 조금 아래와 같이 추가할 수도 있다.

type Omit<T, K extends keyof string | number | symbol> = Pick<
  T,
  Exclude<keyof T, K>
>

https://github.com/microsoft/TypeScript/blob/546a87fa31086d3323ba4843a634863debb75781/lib/lib.es5.d.ts#L1513-L1516 뭔가 저건 과하다고 생각한건지 any로 퉁쳤다.

Omit 과정 다시한번 살펴보기

interface Todo {
  title: string
  description: string
  completed: boolean
  createdAt: number
}

type TodoWithoutTitle = Omit<Todo, 'title'>

type TodoWithoutTitle = Pick<Todo, Exclude<keyof Todo, 'title'>>

type TodoWithoutTitle = Pick<
  Todo,
  Exclude<'title' | ' description' | 'completed' | 'createdAt', 'title'>
>

type TodoWithoutTitle = Pick<
  Todo,
  | ('title' extends 'title' ? never : 'title')
  | ('description' extends 'title' ? never : 'description')
  | ('completed' extends 'title' ? never : 'completed')
  | ('createdAt' extends 'title' ? never : 'createdAt')
>

type TodoWithoutTitle = Pick<
  Todo,
  never | 'description' | 'completed' | 'createdAt'
>

type TodoWithoutTitle = {
  [Key in 'description' | 'completed' | 'createdAt']: User[Key]
}

type TodoWithoutTitle = {
  description: Todo['description']
  completed: Todo['completed']
  createdAt: Todo['createdAt']
}

type TodoWithoutTitle = {
  description: string
  completed: boolean
  createdAt: number
}

관련 글

  • #typescript#oxc#eslint

    typescript@7을 설치하면 벌어지는 일들: 블로그 모노레포 마이그레이션 기록

    pnpm lint가 12분 32초 걸리던 모노레포에 typescript 7.0.2를 넣어봤다. 타입체크는 조용히 지나갔는데 next build가 깨졌고, lint는 크래시했다. eslint와 prettier를 oxlint와 oxfmt로 갈아탄 하루의 연쇄 반응과 전후 실측 기록. 미리 말해두면, 빌드는 빨라지지 않았다.

    2026-08-10·17분
  • #typescript#backend

    Effect 시스템 심층 분석: 모나드에서 Algebraic Effects까지, 그리고 Effect-TS의 선택

    Effect-TS가 대체 뭔데 다들 난리인지 직접 파헤쳐봤다.

    2026-02-20·41분
  • #typescript

    TypeScript에서 switch문의 모든 케이스를 빠짐없이 처리했는지 검사하는 방법

    never 타입을 활용한 exhaustive check 패턴

    2026-01-17·13분
  • #react#typescript

    useEvent에서 useEffectEvent까지: React의 이벤트 핸들러 안정화 여정

    3년 전 RFC가 드디어 빛을 보다

    2025-12-15·24분

새 글을 놓치고 싶지 않으시다면 RSS로 구독해 주세요.

RSS 구독 →

yceffort — 프론트엔드 엔지니어입니다. 발표·기술 자문·기고 문의는 이곳에서 받고 있습니다.

← Back to the blogIssue on GitHub →