Guard : 지키다, 보호하다
타입 가드가 무엇인지 아래의 간단한 예시들과 함께 살펴보도록 하겠습니다.
예시 1
function logText(el: Element) {
console.log(el.textContent);
}
const h1El = document.querySelector("h1");
logText(h1El); // 타입 에러 발생
함수 logText는 매개 변수 el의 타입이 Element(HTML 요소)로 명시되어 있으며, 변수 h1El에 h1 요소를 찾아 할당하고 해당 변수를 함수 logText의 인수로 전달하고 있습니다.
타입 단언과 할당 단언
단언 : 주저하지 아니하고 딱 잘라 말함 타입 단언 타입 단언은 타입스크립트의 중요한 개념으로 어렵지 않게 사용할 수 있지만 잘못 사용할 경우 any 타입처럼 타입스크립트를 사용하는 이유가
nicehyun12.tistory.com
![](https://blog.kakaocdn.net/dn/dVaeb3/btrU9dqjh0X/BGxJNcinkO8Zwk9JdyRKg1/img.png)
앞서 작성한 타입 단언 게시글에서 살펴보았듯 타입스크립트는 h1요소가 있는지 알지 못하기 때문에 null이 반환될 수도 있다고 타입을 추론하게 됩니다.
함수 logText의 매개 변수는 인수로 Element 타입의 데이터를 전달받는다고 명시되어 있는데 인수로 전달되는 변수 h1El이 null일수도 있기 때문에 위와 같은 타입 에러가 발생하게 됩니다.
const h1El = document.querySelector("h1") as HTMLHeadingElement; // 타입 단언
logText(h1El);
이 경우 위와 같이 h1 요소가 존재한다고 타입스크립트에 단언을 해주게 되면 타입스크립트는 개발자가 h1 요소가 존재한다고 확신하고 있다고 여겨 타입 에러가 제거되게 됩니다. h1 요소가 개발자의 단언처럼 존재한다면 문제가 되지 않겠지만 h1 요소가 존재하지 않다면 타입 단언의 잘못된 사용으로 해당 타입 에러를 코드가 아닌 런타임에서 확인하게 될 것이고, 이로 인해 타입스크립트 사용 이유가 사라지게 될 것입니다.
const h1El = document.querySelector("h1") as HTMLHeadingElement;
if (h1El) {
logText(h1El);
}
이때 타입 단언을 하지 않고 위와 같이 조건문을 사용하여 변수 h1El이 falsy, 즉 null이 아닐 경우만 함수 logText에 인수로 전달하게 코드를 작성해주게 되면 더 이상 에러가 발생하지 않게 됩니다. 이렇게 작성한 조건문이 타입 가드입니다.
타입 가드는 실제로 데이터가 존재할 때만, 즉 falsy가 아닐 때만 동작하도록 만들어주는데, 어떻게 보면 타입스크립트와 상관없게 느껴질 수도 있지만, 이러한 개념이 타입 가드에 해당합니다.
const h1El = document.querySelector("h1") as HTMLHeadingElement;
if (h1El instanceof HTMLHeadingElement) { //HTMLHeadingElement 클래스의 인스턴스이면
logText(h1El);
}
추가로 조건문에 들어가는 h1El을 보다 명확히 명시하기 위해 위와 같이 instanceof를 사용하여 HTMLHeadingElement의 인스턴스일 때 조건문 안의 실행문이 실행되도록 해주었습니다.
예시 2
function add(val: string | number) {
let res = "Result =>";
if (typeof val === "number") {
res += val.toFixed(2);
} else {
res += val.toUpperCase();
}
console.log(res);
}
add(3.141592);
add("hello");
함수 add의 매개 변수 val은 위와 같이 union 타입으로 명시되어 있으며 내부의 조건문에 매개변수 val의 타입이 number이면 toFixed 메서드를 사용한 뒤 변수 res에 더해주고, number 타입이 아니면 toUpperCase 메서드를 사용한 뒤 변수 res에 더한 뒤 콘솔로 출력하고 있습니다. 이렇게 함수 add에서 조건문을 사용하여 타입 가드를 하고 있습니다.
function add(val: string | number | boolean) {
let res = "Result =>";
if (typeof val === "number") {
res += val.toFixed(2);
} else {
res += val.toUpperCase(); // 타입 에러 발생
}
console.log(res);
}
이때 매개 변수 val의 타입에 boolean을 추가해주게 되면 else 구문에서 타입 에러가 발생하게 되는데, 이는 매개 변수 val에 들어오는 인수의 타입이 number가 아니면 else 구문에서 toUpperCase 메서드를 사용하게 되는데 인수로 boolean이 들어왔을 경우도 else 구문이 실행되기 때문입니다.
function add(val: string | number | boolean) {
let res = "Result =>";
if (typeof val === "number") {
res += val.toFixed(2);
}
if (typeof val === "string") {
res += val.toUpperCase();
}
console.log(res);
}
위의 코드처럼 매개 변수 val의 타입 가드를 보다 명확하게 작성해주게 되면 타입 에러는 사라지게 됩니다.
'TypeScript' 카테고리의 다른 글
타입 별칭(Alias) (0) | 2023.01.02 |
---|---|
인터페이스 (Interface) (2) | 2023.01.02 |
타입 단언과 할당 단언 (0) | 2023.01.02 |
타입 추론 (Inference) (2) | 2023.01.01 |
TypeScript 타입 종류 (0) | 2023.01.01 |