[Typescript] Type Guard

한별·2023년 12월 5일
0

TypeScript

목록 보기
3/5

Type Guard

Type guard를 사용하면 조건문에서 객체의 타입을 좁혀나갈 수 있다.

⭐ typeof

function doSomething(x: number | string) {
  if (typeof x === 'string') {
    console.log(x.substr(1)); // Ok
  }
  x.substr(1); // Error: `x`가 `string`이라는 보장 없음
}

⭐ instanceof

class Foo {
  foo = 123;
  common = '123';
}

class Bar {
  bar = 123;
  common = '123';
}

function doStuff(arg: Foo | Bar) {
  if (arg instanceof Foo) {
    console.log(arg.foo); // Ok
    console.log(arg.bar); // Error
  }
  if (arg instanceof Bar) {
    console.log(arg.foo); // Error
    console.log(arg.bar); // Ok
  }

  console.log(arg.common); // Ok
  console.log(arg.foo); // Error
  console.log(arg.bar); // Error
}

doStuff(new Foo());
doStuff(new Bar());

⭐ in

in 연산자를 이용한 조건문으로 속성 포함 여부를 체크한다.

interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

type Person = User | Admin;

export function logPerson(person: Person) {
    let additionalInformation: string;
    if ('role' in person) { // check
        additionalInformation = person.role;
    } else {
        additionalInformation = person.occupation;
    }
    console.log(` - ${person.name}, ${person.age}, ${additionalInformation}`);
}

⭐ is : 사용자 정의 Type Guard

일반 Javascript 객체 {} 를 사용할 때는 instanceof, typeof를 사용할 수 없다.

export const persons: Person[] = [
    { type: 'user', name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
    { type: 'admin', name: 'Jane Doe', age: 32, role: 'Administrator' },
    { type: 'user', name: 'Kate Müller', age: 23, occupation: 'Astronaut' },
    { type: 'admin', name: 'Bruce Willis', age: 64, role: 'World saver' }
];

// 사용자 정의 Type Guard //
export function isAdmin(person: Person): person is Admin {
    return person.type === 'admin';
}

export function isUser(person: Person): person is User {
    return person.type === 'user';
}
//////////////////////////

export function logPerson(person: Person) {
    let additionalInformation: string = '';
    if (isAdmin(person)) {
        additionalInformation = person.role;
    }
    if (isUser(person)) {
        additionalInformation = person.occupation;
    }
    console.log(` - ${person.name}, ${person.age}, ${additionalInformation}`);
}

참고 자료

타입 가드 | TypeScript Deep Dive
Excercise#3 | TypeScript Exercises
Excercise#4 | TypeScript Exercises

profile
누구나 이해하기 쉽게 글 쓰고 싶은 FE 개발자

0개의 댓글