타입 가드
✍️ Type guard (타입 보호): 정확한 의미 전달을 위해 "type guard"는 한글로 번역하지 않았습니다.
Type Guard
Type guard를 사용하면 조건문에서 객체의 타입을 좁혀나갈 수 있습니다.
typeof
typeofTypeScript는 JavaScript의 instanceof, typeof 연산자를 이해할 수 있습니다. 즉 조건문에 typeof와 instanceof를 사용하면, TypeScript는 해당 조건문 블록 내에서는 해당 변수의 타입이 다르다는 것(=좁혀진 범위의 타입)을 이해한다는 것이죠. 아래 예시를 보시면 TypeScript는 특정 메소드(String.prototype.substr)가 string에 존재하지 않는다는 사실을 인식해 사용자 오타가 있을 수 있음을 지적하고 있습니다.
function doSomething(x: number | string) {
if (typeof x === 'string') { // TypeScript는 이 조건문 블록 안에 있는 `x`는 백퍼 `string`이란 걸 알고 있습니다.
console.log(x.subtr(1)); // Error: `subtr`은 `string`에 존재하지 않는 메소드입니다.
console.log(x.substr(1)); // ㅇㅋ
}
x.substr(1); // Error: `x`가 `string`이라는 보장이 없죠.
}instanceof
instanceof아래는 Class와 instanceof에 관한 예제입니다:
TypeScript는 else 또한 이해하기 때문에 우리가 if문으로 타입을 하나 좁혀내면, else문 안의 변수 타입은 절대 동일한 타입이 될 수는 없음을 인지합니다. 아래 예시를 살펴보겠습니다:
in
inin은 객체 내부에 특정 property가 존재하는지를 확인하는 연산자로 type guard로 활용할 수 있습니다. 가령:
리터럴 Type Guard
리터럴 값의 경우 === / == / !== / != 연산자를 사용해 타입을 구분할 수 있습니다.
이는 union 타입에 리터럴 타입이 있는 경우에도 동일하게 적용됩니다. union 타입의 공통 property 값을 비교해 union 타입을 구분할 수 있습니다. 가령:
null과 undefined (strictNullChecks)
null과 undefined (strictNullChecks)TypeScript는 a == null / != null로 null과 undefined 모두 걸러낼 만큼 똑똑한 친구입니다. 가령:
사용자 정의 Type Guards
JavaScript 언어는 풍부한 런타임 내부 검사(=runtime introspection support)를 지원하진 않습니다. 일반 JavaScript 객체(구조적 타입 structural typings 활용)를 사용할 때에는 instanceof나 typeof와 같은 연산자를 액세스 조차 할 수 없습니다. 하지만 TypeScript에서는 사용자 정의 Type Guard 함수를 만들어 이를 해결할 수 있습니다. 사용자 정의 Type Guard 함수란 단순히 어떤 인자명은 어떠한 타입이다라는 값을 리턴하는 함수일 뿐입니다. 아래에 예시를 보겠습니다:
Type Guard와 Callback
TypeScript는 콜백 함수 내에서 type guard가 계속 유효하다고 여기지 않습니다. 이는 매우 위험하기 때문입니다. 가령:
해결법은 아주 간단합니다. 로컬 변수를 선언하고 그 안에 값을 담아 타입 추론이 가능하도록 만드는 것이죠. 이는 해당 변수의 타입이 외부 요인으로 인해 바뀔 가능성이 없다는 걸 자동으로 보장하고, TypeScript 또한 이를 쉽게 이해할 수 있습니다:
Last updated
Was this helpful?