몽땅뚝딱 개발자

[TypeScript] 타입 좁히기 본문

Development/Typescript

[TypeScript] 타입 좁히기

레오나르도 다빈츠 2022. 11. 20. 16:10

 

📍 클릭 시 이동!

1. 분기문 사용하기

2. instanceof 사용하기

3. 속성 체크하기

4. 명시적 '태그' 붙이기

5. 사용자 정의 타입 가드 사용하기

추가. 주의할 점

 


 

 

 

◽ 1. 분기문 사용하기

예제 1. if문

const el = document.getElementById('foo') // 타입: HTMLElement | null
if(el) {
	el // 타입: HTMLElement
} else {
	el // 타입: null
}

 

예제 2. 에러 던지기

const el = document.getElementById('foo') // 타입: HTMLElement | null
if(!el) throw new Error('변수를 찾을 수 없습니다.')
el // 타입: HTMLElement

 

 

 

◽ 2. instanceof 사용하기

function contains(text: string, search: string|RegExp) {
	if(search instanceof RegExp) {
    	search // 타입: RegExp
        return !!search.exec(text);
    }
    search // 타입: string
    return text.includes(search);
}

 

 

 

◽ 3. 속성 체크하기

interface A {
  a: number
}

interface B {
  b: number
}

function pockAB(ab: A | B) {
  if ('a' in ab) {
    ab // 타입: A
  } else {
    ab // 타입: B
  }
  ab // 타입: A | B
}

 

 

◽ 4. 명시적 '태그' 붙이기

이 패턴은 '태그된 유니온(tagged union)' 또는 '구별된 유니온(discriminated union)'이라고 불린다.

interface UploadEvent {
  type: 'upload'
  filename: string
}

interface DownloadEvent {
  type: 'download'
}

type AppEvent = UploadEvent | DownloadEvent

function handleEvent(e: AppEvent) {
  switch (e.type) {
    case 'upload':
      console.log(typeof e) // 타입: UploadEvent
      break
    case 'download':
      console.log(typeof e) // 타입: DownloadEvent
      break
  }
}

 

이렇게 자동완성도 해준다.

 

 

 

◽ 5. '사용자 정의 타입 가드' 사용하기

타입스크립트가 타입을 식별하지 못한다면, 식별을 돕기 위해 커스텀 함수를 도입할 수도 있다.

반환 타입으로 사용된 'el is HTMLInputElement' 구문은 함수의 반환이 true인 경우 타입 체커에게 매개변수의 타입을 'HTMLInputElement'로 좁힐 수 있다고 알려준다.

 

이런 기법을 '사용자 정의 타입 가드'라고 한다.

function isInputElement(el: HTMLElement): el is HTMLInputElement {
  return 'value' in el
}

function getElementContent(el: HTMLElement) {
  if (isInputElement(el)) {
    console.log(typeof el) // 타입: HTMLInputElement
    return el.value
  }

  console.log(typeof el) // 타입: HTMLElement
  return el.textContent
}

 

 

💡 주의할 점

타입 스크립트는 조건문에서 타입을 좁히는 데 능숙하지만 주의가 필요하다.

1. null은 Object이다.

const el = document.getElementById('foo') // 타입: HTMLElement | null

// 유니온 타입에서 null을 제외하기 위한 조건문 같지만, null이 object 형태이기 때문에 제외되지 않았다.
if (typeof el === 'object') {
  console.log(typeof el) // 타입: HTMLElement | null
}

 

 

 

2. 빈 문자열과 0은 false이다.

function foo(x?: number | string | null) {
  if (!x) {
    // 빈 문자열('')과 0은 false가 되기 때문에 타입은 전혀 좁혀지지 않는다.
    console.log(typeof x) // 타입: number | string | null | undefined
  }
}

 

타입스크립트가 추정한 타입

 

 


 

 

출처

댄 밴터캄, 이펙티브 타입스크립트 (프로그래밍 인사이트, 2021)

 

 

 


개인적으로 공부한 내용을 정리하는 블로그로
잘못된 개념을 게시하지않도록 주의하고 있으나 오류가 있을 수 있습니다.

 

 

 

 

Comments