typescript

User defined type guards 에 관하여

weaklion 2023. 2. 24. 18:58

이전에 타입 가드에 대해 이야기한 적이 있습니다.

오늘은 유저 정의 타입 가드에 대해 간단히 이야기 해보죠.

타입가드는 컴파일러가 타입을 예측할 수 있도록 타입을 좁혀 타입을 더 명확하게 보장할 수 있도록 합니다.

타입 가드엔 여러가지가 있습니다.

Javascript에 이미 존재하는 typeof, instanceof 연산자를 이용해 타입 가드를 할 수도 있죠.

하지만 오늘은 제목이 user defined type guards이니까 이것에 대해 알아보도록 합시다.

interface Animal {
  name: string;
  age: number;
}

interface Flower {
  type: string;
  age: number;
}

interface ExampleInfo {
  page: number;
  infoBody: Animal | Flower;
}

function isAnimal(arg: any): arg is Animal {
  return arg.name !== undefined;

}

function doSomething(arg: ExampleInfo) {
  const { page, infoBody } = arg;

  if (isAnimal(infoBody)) {
    console.log(infoBody.name);
  } else {
    console.log(infoBody.type); // OK
    console.log(infoBody.name); // error
  }
}

한 블로그에서 가져온 코드입니다.

중점적으로 봐야할 건 doSomething 함수와 isAnimal 함수 두가지 입니다.

 

isAnimal에 arg is Animal이라고 쓰여 있는데 이건 arg의 타입이 animal이라고 가정한다고 이해하시는게 편합니다.

가정을 토대로 isAnimal을 함수를 이해한다면 arg라는 파라미터에 name이 있다면 isAnimal은 true를 반환합니다.

 

doSomething 함수에선 exampleInfo를 타입으로 받습니다.

여기서 우리가 봐야할 건 page가 아닌 infoBody입니다. 

infoBody의 타입은 Animal | Flower입니다.

만약 다른곳에서 IfnoBody를 쓸려고 한다면 둘 사이의 교집합인 age만 사용하고 나머지 키값에 대해선 에러를 출력하겠죠.

 

여기서 방금 만들었던 isAnimal 과 doSomething을 이용합니다.

isAnmial에 infobody를 넣고 if문을 돌리면 우리가 원하는 타입을 얻을 수 있겠죠.

 

 

user defined type guards는 다른 방법으로 이용할 수 있습니다.

isAnimal도 함수이기 때문에 return에 다른 값을 넣으면 타입을 구분할 때에 좀 더 좁혀서 원하는 결과를 얻을 수 있겠죠.

 

저 같은 경우 user defined type guards를 제법 응용하여 사용하고 있습니다.

타입을 명확하게 정의하면 컴파일 단계에서 사이드 이펙트를 좀 더 줄일 수 있죠. 

타입 가드를 잘 활용한다면 타입스크립트를 좀 더 다이나믹하게 사용하실 수 있을 겁니다.