Programming Language/JS & TS

[TS] Type Guard 와 as 키워드

monkeykim 2024. 10. 31. 01:19

TypeScript를 사용하다보면 유니온 타입(|) 을 자주 만나게 됩니다. 유니온 타입은 여러 타입이 혼합된 경우를 의미하는데, 코드의 안전성을 높여주지만, 다양한 타입이 섞여 있으면 원하는 기능을 작성하기 어려울 수 있습니다. 이때 타입 가드(type guard)를 사용하면 특정 타입을 확인하고 좁힐 수 있어, 더 안전한 코드를 작성할 수 있습니다.


타입 가드(Type Guard)란?

타입 가드(type guard)는 특정 조건을 통해 유니온 타입을 특정 타입으로 좁히는 방법입니다. 이를 통해 TypeScript는 조건문 내부에서 해당 타입을 안전하게 사용할 수 있게 도와줍니다.

 

in 연산자를 활용한 타입가드 예시

type Dog = { bark: () => void };
type Cat = { meow: () => void };

function makeSound(animal: Dog | Cat) {
  if ("bark" in animal) {
    // 여기서 animal은 Dog 타입으로 좁혀집니다.
    animal.bark();
  } else {
    // 여기서 animal은 Cat 타입으로 좁혀집니다.
    animal.meow();
  }
}

이 코드에서는 Dog 타입에만 있는 bark 메소드를 이용해 animal이 Dog인지 Cat인지 구분하고 있습니다. TypeScript는 bark 가 있으면 Dog, 없으면 Cat으로 추론하게 됩니다.

 

1. 타입 가드의 종류

  • in 연산자: 특정 속성의 유무로 타입을 구분합니다.
  • typeof 연산자: 기본형 타입(string, number, boolean 등)을 구분할 때 사용합니다.
  • 사용자 정의 타입 가드 함수: 더 복잡한 조건이 필요할 때 직접 타입 가드를 만들어서 사용합니다.

사용자 정의 타입 가드 함수 예시

type Fish = { swim: () => void };
type Bird = { fly: () => void };

function isFish(animal: Fish | Bird): animal is Fish {
  return (animal as Fish).swim !== undefined;
}

function move(animal: Fish | Bird) {
  if (isFish(animal)) {
    // animal이 Fish 타입으로 좁혀집니다.
    animal.swim();
  } else {
    // animal이 Bird 타입으로 좁혀집니다.
    animal.fly();
  }
}

이 코드에서 isFish 함수는 Fish 타입에만 있는 swim 메소드를 확인해 animal이 Fish인지 아닌지 판단합니다. 여기서 animal is Fish라는 리턴 타입이 중요한데, 이는 TypeScript에게 이 함수는 타입가드 함수임을 알려주는 표기입니다.


as 키워드란?

as 키워드는 타입 단언(Type Assertion)으로, TypeScript 컴파일러에게 특정 변수를 특정 타입으로 간주하도록 하는 방법입니다. 이는 개발자가 변수의 타입을 더 잘 알고 있을 때 사용할 수 있는데, TypeScript는 지정된 타입으로 해당 변수를 처리합니다.

 

예를 들어, HTMLElement 타입에서 HTMLDivElement로 타입을 좁히고 싶다면,

const element = document.getElementById("myDiv") as HTMLDivElement;
element.style.backgroundColor = "blue";

위와 같이 as를 사용할 수 있습니다.

여기서 document.getElementById는 HTMLElement | null 타입을 반환하기 때문에, element가 HTMLDivElement임을 확신한다면 as를 통해 강제로 타입을 지정할 수 있습니다.

 

as 키워드는 특히 외부 데이터를 다룰 때 유용한데, 서버에서 받아온 data 객체가 문자열이라고 가정하고 다음과 같이 단언할 수 있습니다.

const data: unknown = "Hello, TypeScript!";
const message = data as string;
console.log(message.toUpperCase()); // "HELLO, TYPESCRIPT!"

이 코드에서 data의 타입이 unknown이지만, as string 을 통해 TypeScript에게 data가 문자열임을 명확히 알려주고 toUpperCase 메소드를 안전하게 호출할 수 있습니다.


정리

타입 가드(Type Guard)는 조건을 통해 타입을 좁히는 과정이며, TypeScript가 타입 안전성을 유지하면서 조건에 따라 타입을 추론할 수 있게 합니다.

 

as 키워드는 TS 컴파일러가 지정한 타입을 무시하고, 강제로 타입을 단언하는 방법으로, 주로 개발자가 타입을 더 잘 알고 있다고 확신할 때 사용하지만, 실제 타입과 맞지 않으면 런타임 에러가 발생할 수 있습니다.