[TypeScript] 타입 좁히기

Dae-Hee·2023년 7월 12일
0

Typescript Study

목록 보기
11/11
post-thumbnail

타입 가드를 적절하게 사용하여 타입을 좁혀가자


범용성 있는 공통 함수를 구현하기 위해서는 타입 좁히기가 중요하다.

컴파일러에서 제어 흐름 분석을 진행할 시 타입 가드를 마주하게 되면 타입 좁히기가 발생
*대부분의 제어문 을 통해 타입가드를 설정할 수 있다.

  • if
  • switch
  • break
  • throw
  • return

▪︎ null 체크 및 typeof, instanceof 연산자

const fnc = (arg: string | number) => {
  if (typeof arg === 'string') {
    // arg > string 타입 추론
  } else {
    // arg > number 타입 추론
  }
}

// 단순히 null 체크의 경우
const fnc = (arg?: string) => {
  if (arg) {
    // arg > string 타입 추론
  } else {
    // arg > null 타입 추론
  }
}

// thorw를 통해 좁히기 가능
const fnc = (arg?: string) => {
  if(!arg) throw new Error('에러 발생!');
  // arg > string 타입 추론
}

const fnc = (arg: any) => {
  if(typeof arg === 'object') {
  	// arg > object | null 타입 추론
    // null이 object 형태이기 때문에 제외되지 않았다.  
  }
}

const fnc = (arg: number | string | null) => {
  if (!arg) {
    // '', 0 === false 이기 때문에 타입 가드가 성립이 안된다.
  }
}

▪︎ in 연산자

interface Guest {
  guestId: number;
  name: string;
}

interface Admin {
  adminId: number;
  name: string;
}

const fnc = (user: Guest | Admin) => {
  if ('guestId' in user) {
    // user > Guest 타입 추론
  }
  // user > Admin 타입 추론
}

▪︎ 동등(===) 연산자

const fnc = (a: number | string, b: number | boolean) => {
  if (a === b) {
    // a, b 모두 number 타입 추론
  }
}

▪︎ 명시적 태그

interface Guest {
  guestId: number;
  name: string;
  role: 'guest';
}

interface Admin {
  adminId: number;
  name: string;
  role: 'admin';
}

type User = Guest | Admin;

const fnc = (user: User) => {
  switch (user.role) {
    case 'guest':
      // user > Guest 타입 추론
      break
    case 'admin':
      // user > Admin 타입 추론
      break
  }
}

▪︎ 사용자 정의 타입 가드

interface Fish {
  swim: () => void;
}

interface Bird {
  fly: () => void;
}

const isFish = (pet: Fish | Bird): pet is Fish =>
  (pet as Fish).swim !== undefined;

if (isFish(pet)) {
  // pet > Fish 타입 추론
  pet.swim();
}
else {
  // pet > Bird 타입 추론
  pet.fly();
}
pet is Fish > 함수가 호출된 범위 내에선 pet을 Fish타입으로 보라
is 키워드는 컴파일 단계에서만 사용되며 런타임 단계에서는 순수한 js 파일과 동일하게 동작

- as는 타입 단언으로, 컴파일 단계에서 타입스크립트가 잘못 혹은 보수적으로 타입을 추론하는 경우 
  개발자가 수동으로 컴파일러에게 특정 변수에 대한 타입 힌트를 주는 것
  
- is는 타입 가드로, 한정된 범위 내의 모든 변수에 대해서 일괄적으로 적용할 수 있는 키워드


Reference

0개의 댓글