[TypeScript] 타입스크립트 타입 가드 (Type Guard)
글 작성자: 망고좋아
반응형
🎯 타입스크립트 타입 가드(Type Guard)
- 데이터의 타입을 알 수 없거나, 될 수 있는 타입이 여러 개라고 가정할 때 조건문을 통해 데이터의 타입을 좁혀나가는 것
- 데이터의 타입에 따라 대응하여 에러를 최소화할 수 있음
- 타입을 통해 '가드'하는 코드, 방어적인 코드를 짤 수 있음
📝 타입 가드를 사용해 유니온 타입 사용
// 구별된 유니온
type Human = {
think: () => void;
};
type Dog = {
bark: () => void;
}
declare function getEliceType(): Human | Dog;
const elice = getEliceType();
- elice가 Human인지, Dog인지 확신할 수 없는 상태
- 타입스크립트가 타입을 추론할 수 있도록 단서를 줘보면 어떨까?
📕 구별된 유니온
- 타입을 구별할 수 있는 단서가 있는 유니온 타입
- 구별된 유니온, 태그 된 유니온, 서로소 유니온이라는 다양한 이름을 가지고 있다.
📝 구별된 유니온으로 타입 가드 하는 방법
type Human = {
think: () => void;
};
type Dog = {
tail: string; // 구별한 단서(태그)
bark: () => void;
}
declare function getEliceType(): Human | Dog;
const elice = getEliceType();
if ('tail' in elice) {
elice.bark(); // Dog 타입으로 추론할 수 있다.
} else {
elice.think(); // Human 타입으로 추론할 수 있다.
}
- 첫 번째, 각 타입에 타입을 구별한 단서(태그)를 만든다.
- 두 번째, 조건문을 통해 각 타입의 단서로 어떤 타입인지 추론한다.
- 세 번째, 해당 타입의 프로퍼티를 사용한다.
📝 실무에서 자주 쓰는 구별된 유니온과 타입 가드
type SuccessResponse = {
status: true;
data: any;
};
type FailureResponse = {
status: false;
error: Error;
};
type CustomResponse = SuccessResponse | FailureResponse;
declare function getData(): CustomResponse;
const response: CustomResponse = getData();
if(response.status) {
console.log(response.data);
} else if (response.status === false) {
console.log(response.error);
}
- 서버에서 오는 응답 또는 함수의 결과가 여러 갈래로 나뉠 때 구별된 유니온 사용 가능
- 타입의 단서를 토대로 타입 가드를 하고, 응답의 결과에 따라 다른 작업을 실행시켜준다.
📝 instanceof를 사용한 타입 가드
class Developer {
developer() {
console.log("업무 중")
}
}
class Designer {
design() {
console.log("업무 중")
}
}
const work = (worker: Developer | Designer) => {
if (worker instanceof Developer) {
worker.developer();
} else {
worker.design();
}
}
- TS에서는 클래스도 타입이다.
- 객체가 어떤 클래스의 객체인지 구별할 때 사용하는 연산자.
인스턴스 intanceof 클래스
와 같이 사용
📝 typeof를 사용한 타입 가드
const add = (arg?: number) => {
if (typeof arg === 'undefined') {
return 0;
}
return arg + arg;
}
- 데이터의 타입을 반환하는 연산자.
typeof 데이터 === 'string'
과 같이 사용typeof 데이터 === 'undefined'
처럼 undefined 체크도 가능- 참고로
데이터 == null
과 같이 쓰면 null, undefined 둘 다 체크 ⇒ 일치 연산자(===
)가 아닌 동등 연산자(==
) 사용 - null과 undefined는 따로 체크해주는 게 더 명확하다.
📝 in을 사용한 타입 가드
type Human = {
think: () => void;
};
type Dog = {
tail: string;
bark: () => void;
}
declare function getEliceType(): Human | Dog;
const elice = getEliceType();
if ('tail' in elice) {
elice.bark();
} else {
elice.think();
}
문자열 A in Object
: object의 key 중에 문자열 A가 존재하는지 확인함- 문자열 A는 object의 key를 의미한다.
📝 literal type guard
type Action = 'click' | 'hover' | 'scroll';
const doPhotoAction = (action: Action) => {
switch (action) {
case 'click':
showPhoto()
break;
case 'hover':
zoomInPhoto()
break;
case 'scroll':
loadPhotoMore()
break;
}
}
// or
const doPhotoAction2 = (action: Action) => {
if(action === 'click') {
showPhoto();
} else if (action === 'hover') {
zoomInPhoto();
} else if (action === 'scroll') {
loadPhotoMore();
}
}
- 리터럴 타입 : 특정 타입의 하위 타입(구체적인 타입)이다. ex) string 타입의 리터럴 타입: ‘cat’, ‘dog’, …
- 즉, string 문자열 타입에 속하는 구체적인 값들을 리터럴 타입이라고 부른다.
- 리터럴 타입은 동등(==), 일치(===) 연산자 또는 switch로 타입 가드 가능
- 하나의 value 값에 따라 조건문을 작성하는 경우, 대부분의 경우 switch의 연산 결과가 if-else보다 더 빠르므로 되도록 switch를 쓰는 걸 권장
- 조건문의 개수가 적으면 큰 차이는 없지만, 조건문의 개수가 많아질수록 switch의 성능이 더 빠르다.
📝 Type guard에 유용한 오픈소스 - sindresorhus/is
import is from '@sindresorhus/is';
const getString = (arg?: string) => {
if(is.nullOrUndefined(arg)) {
return '';
}
if(is.emptyStringOrWhitespace(arg)) {
return '';
}
return arg;
}
- 사용자 정의 함수를 사용해 타입 가드 가능
- 오픈소스 중 sindresorhus/is를 사용하여 가독성 있게 타입 체크 가능
yarn add @sindersorhus/is
또는npm install @sindersorhus/is
- https://github.com/sindresorhus/is
반응형
'프로그래밍 > TypeScript' 카테고리의 다른 글
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator) (1) | 2021.11.29 |
---|---|
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining) (0) | 2021.11.29 |
[TypeScript] 타입스크립트 유니온 타입 & 인터섹션 타입 (Union Type & Intersection Type) (0) | 2021.11.29 |
[TypeScript] 타입스크립트 제네릭(Generic), Factory Pattern with Generics (0) | 2021.11.27 |
[TypeScript] 타입스크립트 인터페이스(Interface), Strategy pattern (0) | 2021.11.27 |
댓글
이 글 공유하기
다른 글
-
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
[TypeScript] 타입스크립트 null 병합 연산자 (Nullish Coalescing Operator)
2021.11.29 -
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
[TypeScript] 타입스크립트 옵셔널 체이닝 (Optional Chaining)
2021.11.29 -
[TypeScript] 타입스크립트 유니온 타입 & 인터섹션 타입 (Union Type & Intersection Type)
[TypeScript] 타입스크립트 유니온 타입 & 인터섹션 타입 (Union Type & Intersection Type)
2021.11.29 -
[TypeScript] 타입스크립트 제네릭(Generic), Factory Pattern with Generics
[TypeScript] 타입스크립트 제네릭(Generic), Factory Pattern with Generics
2021.11.27