타입가드

타입스크립트

타입가드란

타입가드는 에러를 줄일 수 있는 방어 코드 기법을 의미

대표적인 타입가드 키워드들로

  1. typeof: 일반 타입 체크
  2. instanceof: 클래스 체크
  3. Array.isArray(): 배열 체크
  4. .type / in: 객체 속성 체크

이는 모두 자바스크립트 코드인데, 오히려 자바스크립트에서는 타입에 유연하기 때문에 쓸일이 자주 없지만

타입스크립트에선 자주 사용한다고 한다

일반 타입 가드(typeof)

function numOrStr(a: number | string) {
	if (typeof a === "string") a.split(',');
	// 소수 두번째 자리에서 반올림
	if (typeof a === "number") a.toFixed(1);
}

if 문 뿐만 아니라 switch문에서도 사용할 수 있다 switch (typeof a) 이런느낌으로..

배열 타입 가드 (Array.isArray())

function numOrNumArr(a: number | number[]) {
	if (Array.isArray(a)) a.slice(1);
	else a.toFixed(1);
}

클래스 타입 가드 (instanceof)

class Animal {
	voice() {}
}
 
function Cat(param: Animal | string) {
	if (param instanceof Animal) {
		param.voice();
	} else {
		console.log(param);
	}
}
Cat(new Animal());
Cat("String");

객체 타입 가드

만일 다음과 같이 Lion, Ant, Sparrow 와 같은 객체 (객체 리터럴) 이 있을 경우 이들을 어떻게 구분 할까?

````ad-cyan
title: 공통속성 비교
```ts
type Lion = { type: "mammal"; gender: "F" | "M"; bite: boolean };
type Ant = { type: "insect"; gender: "F" | "M"; acid: boolean };
type Sparrow = { type: "bird"; gender: "F" | "M"; fly: boolean };
 
function typeCheck(a: Lion | Ant | Sparrow) {
	if (a.type === "mammal") a.bite = true;
	else if (a.type === "insect") a.acid = true;
	else a.fly = true;
}
```
간단하게 이 객체안에 **공통된 속성을 찾아 구분**해주면 된다 (공통속성)
(특별한 꼼수가 존재하지 않고, 그냥 객체마다 **공통된 속성을 사용하여 다르게 구분**)
````
 
````ad-cyan
title:서로 다른속성 비교
```ts
type Lion = { gender: "F" | "M"; bite: boolean };
type Ant = { gender: "F" | "M"; acid: boolean };
type Sparrow = { gender: "F" | "M"; fly: boolean };
 
function typeCheck(a: Lion | Ant | Sparrow) {
	if ('bite' in a) a.bite = true;
	else if ('acid' in a) a.acid = true;
	else a.fly = true;
}
```
반대로 공통된 속성이 존재하지 않을 떄는 어떻게 할까??
 
 **서로 존재하지 않은 속성(key)을 찾아서 구분**해주면 된다 (in)
````

Null 타입 가드

null타입 및 undefined 의 경우 배열 인덱스를 참조하거나, 여타 다른 조작을 할 때 에러가 발생하므로 사전에 타입 가드를 해줘야한다

특히 Null의 경우, 자바스크립트에서 typeof null === 'object' → true 이기 때문에 (혼란 야기) 더욱 타입가드를 해줘야한다

function sample(data: number[] | null) {
	if (data && Array.isArray(data)) {      // 조건문 앞에 data가 null, undefined이면 false로 처리된다
		for (const i of data) console.log(i);
	}
}

사용자 정의 타입가드 (is)

간단한 타입의 경우, 자바스크립트에서 제공하는 키워드를 통해 타입가드를 할 수 있다. 하지만 복잡한 타입을 가드하는 경우에는 타입스크립트에서 is 키워드를 사용하여 타입가드 전용 함수를 만들 수 있다

title: is 키워드
```ts
interface Cat {
	meow: string;
}
interface Dog {
	bow: string;
}
 
function catOrDog(a: Cat | Dog): a is Dog {  // is 키워드 -> Dog 기준으로 참/거짓
	// 타입 판별을 알아서 로직 구현하면 된다
	if ('meow' in a) return false;
	else return true;
}
 
function pet(a: Cat | Dog): void {
	if (catOrDog(a)) console.log(a.bow);
	else console.log(a.meow);
}
```
is 키워드와 boolean이 무슨 차이인지 궁금할 수도 있다. ~~*궁금하면 직접 해보면 된다!*~~
**is 키워드**는 **타입스크립트에서 지원하는 키워드**로, is키워드를 사용하면 **함수가 타입가드로써 의미**있게 된다
boolean으로 반환타입을 지정하면, pet 함수에서 a.bow 나 a.meow에서 에러가 발생한다 (Cat인지 Dog인지 컴파일러는 모르므로)
**is 키워드를 사용**해서 걸러줘야지 **제대로 에러없이 실행 가능**하게 된다

이 밖에도 프로미스 타입가드, 동등 타입기법,, 등등 많은 타입가드 기법들이 존재하는데 이 외의 것들은 그때 그때 필요할 떄 찾아보는 것으로 하자

참고

📘 타입 추론 / 타입 호환 / 타입 단언 / 타입 가드 💯 총정리