혼자 적어보는 노트

[Typescript] Type Guard로 타입 좁히기 본문

Typescript

[Typescript] Type Guard로 타입 좁히기

jinist 2022. 7. 13. 18:43

 

 

타입스크립트 Type Guard로 타입 좁히기

 

Type Guard

컴파일러가 타입을 예측할 수 있도록 타입을 좁혀주어서 타입의 안전함을 보장할 수 있다.

 

 

typeof를 사용한 type guards

Javascript의 typeof 연산자를 활용하여 타입가드를 할 수 있다.

const test = (a: number | string) => {
  if (typeof a === "string") {
    return a.substring(1);
  }
  return a;
};

함수의 인자로 넘어온 a값은 number이거나 string일 수 있는데

바로 a.substring을 사용하면 number에는 substring을 사용할 수 없기 때문에 에러가 발생한다.

 

typeof를 사용하여 if문 내에서 a값이 string임을 보장을 시킬 수 있다.

 

 

in을 사용한 type guards

Javascript의 in 연산자를 활용하여 객체에 대한 타입가드를 할 수 있다.

type Student = {
  name: string;
  class: number;
};

type OfficeWorker = {
  name: string;
  salary: number;
};

type Person = Student | OfficeWorker;


const test = (info:Person) => {
  console.log(info.name);
  console.log(info.class); // OfficeWorker에는 class가 없기 때문에 에러 발생
  
  if ("class" in info) { // in을 사용하여 TypeGuard 해주면 에러 없이 처리 가능
      console.log(info.class);
  }
}

 

instanceof를 사용한 type guards

Javascript의 instanceof 연산자를 활용하여 클래스에 대한 타입가드를 할 수 있다.

 

class Person {
  greet() {
    console.log("Hi!");
  }
}

class Student {
  greet() {
    console.log("Hello");
  }

  myAge(age: number) {
    console.log("I'm" + age);
  }
}

type User = Person | Student;

const user1 = new Person();
const user2 = new Student();

const test = (user: User) => {
  // user.myAge(100); // Person에는 myAge가 없기 때문에 에러 발생

  if ("myAge" in user) { // in 사용 가능
    user.myAge(100);
  }

  if (user instanceof Student) { // instanceof 사용 가능
    user.myAge(100);
  }
};

in으로도 타입가드가 가능하지만 문자열을 작성하는 것 보다는

instanceof를 사용하는 것이 조금 더 안전하다.

 

 

특정 프로퍼티를 사용한 type guards

객체 안에 구분할 수 있는 프로퍼티를 넣어 타입가드를 할 수 있다.

interface Student {
  type: "student";
  name: string;
  age: number;
}

interface OfficeWorker {
  type: "officeWorker";
  name: string;
  salary: number;
}

type Person = Student | OfficeWorker;

const test = (person: Person) => {
  switch (person.type) {
    case "student":
      return person.age;
    case "officeWorker":
      return person.salary;
  }
};

 

interface에 type을 지정해두고 switch문을 통해 타입가드를 할 수 있다.

Person에 유니온 타입을 지정해두었기 때문에 switch문의 case작성란에서 자동 완성이 가능하다.

 

객체와 유니언 타입을 사용하여 작업할 때 유용한 패턴이라고 한다.

 

 

사용자 정의 type guards

사용자 정의 함수를 만들어서 타입가드를 할 수 있다.

const isAge = (arg: any): arg is Student => {
// age 프로퍼티가 있다면 arg의 타입을 Student로 추론한다.

  return arg.age !== undefined;
};

const test = (person: Person) => {
  if (isAge(person)) {
    return person.age;
  } else {
    return person.salary
  }
};

 

 


Reference

https://chanhuiseok.github.io/posts/ts-2/

https://www.udemy.com/course/best-typescript-21/learn/lecture/27938024#overview

https://radlohead.gitbook.io/typescript-deep-dive/type-system/typeguard

Comments