반응형
타입 가드
타입가드는 자동으로 타입 범위를 좁혀주는 타입스크립트의 기능이다. 생산성과 가독성이 높아지는 효과를 볼 수 있고 as와 같은 극단적인 기능을 쓰지 않아도 된다.
기본 코드
function print(value: number | string){
if(typeof value === 'number') {
console.log((value as number).toFixed(2));
} else {
console.log((value as string).trim(2));
}
}
- 위의 코드에서 as는 타입을 강제로 주입하는 기능으로 어쩔 수 없을때만 사용해야한다. 만약 if 조건문에 number 말고도 string 또한 허용된다면 버그가 생길 위험이 있기 때문이다.
- 원래 if문을 통해 value의 타입을 정해주어 as을 사용했지만 타입 가드의 기능이 있어 사실 as을 쓰지 않아도 자동으로 value의 타입 값을 if문의 조건에 따라 정해주므로 as을 사용하지 않아도 된다.
- 즉 이 기능들이 타입 가드라고 불리며 if문의 조건을 볼 수 있는 타입스크립트의 똑똑함이 드러난다.
class Person {
name: string;
age: number;
constructor(name: string, age: number) {}
}
class Product {
name: string;
price: number;
constructor(name: string, price: number) {}
}
function print(value: Person | Product){
console.log(value.name);
if(value instanceof Person) {
console.log(value.age);
} else {
console.log(value.price);
}
}
- 위와 같이 if문의 instanceof라는 값의 영역에서 사용하는 자바스크립트 기능을 이용하여 value가 class Person의 객체인지 확인하여 value의 타입을 지정해주어 타입 가드의 기능이 발휘하여 자동으로 타입이 지정된다는 것을 알 수 있다.
- 만약 Person class가 들어온다는 이야기는 value의 age 타입이 들어온다는 이야기이고 아니면 Product class가 들어왔다는 이야기 이므로 price 타입이 들어온다는 것을 확인할 수 있다.
interface Person {
name: string;
age: number;
}
interface Product {
name: string;
price: number;
}
function print(value: Person | Product){
console.log(value.name);
if(value instanceof Person) {
console.log(value.age); //오류.
} else {
console.log(value.price); //오류.
}
}
하지만 interface는 타입을 지정하기 위한 코드이고 class와 다르게 컴파일 후 사라지는 것이어서 instanceof가 먹히지 않아 오류가 등장해버린다.
discriminated union
interface Person {
type:'a';
name: string;
age: number;
}
interface Product {
type:'b';
name: string;
price: number;
}
function print(value: Person | Product){
if(value.type === 'a') {
console.log(value.age);
} else {
console.log(value.price);
}
}
- interface을 if문 조건에 걸리게 하는 방법으로 discriminated union라는 것이 있다.
- interface 마다 type이라는 똑같은 키 이름을 지정하고 타입 값을 서로 다르게 하여 구별하는 것이다.
- type ='a'을 가지고 있으면 Person의 inerface 이므로 value에는 age 타입이 들어온다는 것을 확인할 수 있다.
interface Person {
type: 'a';
name: string;
age: number;
}
interface Product {
type: 'b';
name: string;
price: number;
}
function print(value: Person | Product) {
switch (value.type) {
case 'a':
console.log(value.age);
break;
case 'b':
console.log(value.price);
break;
}
}
위에처럼 if문 뿐만 아니라 swich문을 사용하여 interface 각각에 들어있는 type을 이용하여 값의 범위를 구별할 수 있게 되었다.
interface를 구별하는 기타 방법
interface Person {
name: string;
age: number;
}
interface Product {
name: string;
price: number;
}
function isPerson(x: Person | Product): x is Person {
return (x as Person).age != undefined;
}
function print(value: Person | Product) {
if( isPerson(value)){
console.log(value.age)
} else{
console.log(value.price)
}
}
- 위의 코드처럼 따로 interface을 구별하는 함수를 만드는 방법 또한 존재한다.
- is 라는 키워드를 통해 반환값이 Person 타입이 들어오는 검사하고 들어오지 않았다면 undefined을 반환하도록 하였다.
- 그리고 isPerson 함수를 이용하여 타입 가드가 작동되도록 도와주었다.
export {};
interface Person {
type: 'Person';
name: string;
age: number;
}
interface Product {
type: 'Product';
name: string;
price: number;
}
function print(value: Person | Product) {
if( 'age' in value){
console.log(value.age)
} else{
console.log(value.price)
}
}
위의 코드처럼 자바스크립트의 기능인 in을 이용하여 'age'라는 값이 value에 존재하는지 판별하여 Person, Product 둘 중 어떤 interface가 들어왔는지 구별해주어 타입 가드가 작동되도록 도와주었다.
반응형
'프로그래밍 개발 > Typescript' 카테고리의 다른 글
Typescript 타입 추론 (0) | 2021.05.11 |
---|---|
Typescript 조건부 타입 (0) | 2021.05.10 |
Typescript 맵드 타입(mapped type) (0) | 2021.05.10 |
Typescript 재네릭 (0) | 2021.05.07 |
Typescript 타입 호환성 (0) | 2021.05.07 |
댓글