📑 목차
타입스크립트에서는 typeof나 instanceof 같은 연산자로 타입을 좁히기 애매하거나, 더 복잡한 로직으로 타입을 구분해야 할 때가 있다. 이때 사용할 수 있는 것이 사용자 정의 타입 가드다.
쉽게 말해 "참 또는 거짓을 반환하는 함수를 이용해 우리 입맛대로 타입 가드를 만드는 문법" 이다.
1. 기존 방식(in 연산자)의 문제점
먼저 Dog와 Cat 타입을 정의하고, 이를 유니온으로 묶은 Animal 타입을 예로 들어보자.
type Dog = {
name: string;
isBark: boolean;
};
type Cat = {
name: string;
isScratch: boolean;
};
type Animal = Dog | Cat;
기존에 배운 in 연산자를 사용하면 다음과 같이 타입을 좁힐 수 있다.
function warning(animal: Animal) {
if ("isBark" in animal) {
// Dog 타입으로 추론됨
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else if ("isScratch" in animal) {
// Cat 타입으로 추론됨
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
이 코드는 잘 동작하지만 한 가지 단점이 있다.
만약 Dog 타입의 isBark 프로퍼티 이름이 isBarked로 바뀐다면?
타입 정의만 바뀌고 warning 함수 안의 문자열 "isBark"는 그대로 남아있기 때문에, 타입 가드가 제대로 동작하지 않게 된다. 즉, 유지보수가 어렵고 실수를 유발할 수 있다.
2. 사용자 정의 타입 가드 구현 (is 키워드)
이럴 때 함수를 따로 만들어서 타입을 확실하게 검사해주면 좋다. 이때 반환 타입에 사용하는 것이 parameter is Type 문법이다.
// Dog 타입인지 확인하는 타입 가드
function isDog(animal: Animal): animal is Dog {
return (animal as Dog).isBark !== undefined;
}
// Cat 타입인지 확인하는 타입 가드
function isCat(animal: Animal): animal is Cat {
return (animal as Cat).isScratch !== undefined;
}
핵심 포인트: animal is Dog
함수의 반환 타입을 단순히 boolean으로 적는 것이 아니라, animal is Dog라고 적어야 한다.
- 이 함수가
true를 반환하면 -> 인자로 받은animal은Dog타입임이 보장된다는 의미다. - 타입스크립트 컴파일러에게 "내가 검사해봤는데 이거 Dog 맞으니까 믿고 좁혀!"라고 알려주는 것이다.
3. 활용하기
이제 만든 커스텀 타입 가드 함수를 if문의 조건으로 사용하면 된다.
function warning(animal: Animal) {
if (isDog(animal)) {
// 여기 들어왔다는 건 isDog가 true라는 뜻
// 즉, animal은 Dog 타입으로 좁혀짐
console.log(animal.isBark ? "짖습니다" : "안짖어요");
} else if (isCat(animal)) {
// 여기는 Cat 타입
console.log(animal.isScratch ? "할큅니다" : "안할퀴어요");
}
}
이제 프로퍼티 이름이 바뀌더라도 isDog 함수 내부만 수정하면 되고, warning 함수는 건드릴 필요가 없다. 코드가 훨씬 읽기 좋아지고 안전해졌다.
요약
- 사용자 정의 타입 가드: 함수를 이용해 타입을 좁히는 방식이다.
is키워드: 반환 타입에param is Type형식을 사용해야 한다.- 장점:
in연산자처럼 문자열에 의존하지 않으므로, 복잡한 타입 검사 로직을 캡슐화하고 재사용성을 높일 수 있다.
