Type Guard는 변수 유형을 식별하거나 범위를 좁히는 데 사용됩니다.
좁히기 어려운 경우 넓은 범위의 유형을 더 구체적인 유형으로 구체화하는 과정을 의미합니다.
예를 들어, 사람이라는 넓은 범위의 유형을 교사, 의사, 농부 등으로 좁힐 수 있습니다.
주로 이러한 Type Guard는 조건 블록 내에서 사용됩니다.
그리고 Type Guard 메서드는 런타임에 수행되고 boolean 값을 반환합니다.
typeof 는 타입스크립트 또는 자바스크립트의 원시 타입을 검증하거나 식별하기 위한 것입니다.
typeof 키워드의 도움으로 TypeScript는 아래의 원시 타입 변수를 식별할 수 있습니다.
function employeeDetails(emp_: string | number) {
let res_: string = '';
if (typeof emp_ == 'string') {
res_ = Employee name is ${emp_} ;
} else if (typeof emp_ == 'number') {
res_ = Employee age is ${emp_} ;
}
return res_;
}
//first call with a string value
employeeDetails('James');
//second call with a number value
employeeDetails(35);
instanceof는 typeof의 고급 버전으로 사용할 수 있습니다.
typeof 키워드가 변수의 유형을 결정하는 동안
instanceof는 주어진 객체가 특정 클래스 또는 생성자 함수와 유사한 속성을 갖는지 여부를 결정합니다.
그리고 이를 기반으로 boolean 값을 반환합니다.
class Person {
firstName: string;
lastName: string;
constructor(firstName: string, lastName: string) {
this.firstName = firstName;
this.lastName = lastName;
}
}
class Animal {
kind: string;
legs: number;
constructor(kind: string, legs: number) {
this.kind = kind;
this.legs = legs;
}
}
function helloWorld(obj_: Person | Animal) {
let res_: string = '';
if (obj_ instanceof Person) {
res_ = `Welcome ${obj_.firstName} ${obj_.lastName}` ;
} else if (obj_ instanceof Animal) {
res_ = `${obj_.kind} has ${obj_.legs} legs` ;
}
return res_;
}
const james = new Person("James", "Anderson");
const jimmy = new Animal("Dog", 4);
//first call with a person
helloWorld(james);
//second call with an animal
helloWorld(jimmy);
in 은 유형을 서로 구별하는 데 사용할 수 있는 Type Guard입니다.
in 키워드는 선택한 개체에 지정된 속성이 포함되어 있는지 확인합니다.
이 조건에 따라 boolean 값을 반환합니다.
이 키워드는 기능 유효성 검사 및 런타임 문제 방지에 유용합니다.
interface Animal {
group : string;
}
class Fish implements Animal {
group : string;
finsColor : string;
constructor(finsColor: string, group: string) {
this.finsColor = finsColor;
this.group = group;
}
}
class Bird implements Animal {
group : string
feathersColor : string;
constructor(feathersColor: string, group: string){
this.feathersColor = feathersColor;
this.group = group;
}
}
function swim(group : string) {
console.log(${group} can swim! );
}
function fly(group : string) {
console.log(${group} can fly! );
}
function moving(animal : Animal) {
if ('finsColor' in animal) {
swim((animal as Fish).group);
}
else if ('feathersColor' in animal) {
fly((animal as Bird).group);
}
}
//first call with a bird
moving(new Bird('green', 'bird'));
//second call with a fish
moving(new Fish('gold', 'fish'));
Equality Narrowing은 boolean 값이 될 표현식의 값을 반환합니다.
표현식은 두 변수의 값과 제곱이 동일한 경우 true로 반환됩니다. 그렇지 않으면 false를 반환합니다.
이 방법은 부정확한 유형 변수를 식별하는 데 도움이 됩니다.
예를 들어, 한 변수가 부정확한 유형(unknown, any 등)이고 다른 변수가 정확한 유형(number, string 등)이라고 가정합니다.
이 경우 TypeScript는 해당 정보를 사용하여 첫 번째 변수의 유형을 좁힙니다.
function getValues(a: number | string, b: string) {
if(a === b) {
// this is where the narrowing takes place. narrowed to string
console.log(typeof a) // string
} else {
// if there is no narrowing, type remains unknown
console.log(typeof a) // number or string
}
}
//first call with number and string value
getValues(10, '10')
//second call with two string values
getValues('10', '10')
TypeScript에는 미리 정의된 Type Guard 외에 Custom Type Guard를 만들 수도 있습니다.
다음은 동물이 새인지 물고기인지 알아내는 커스텀 타입 가드의 예입니다.
interface Bird{
name: string;
feathersColor: string;
}
interface Fish{
name: string;
finsColor: string;
}
type Animal = Bird | Fish;
/** Custom Type Guard */
const isBird = (animal: Animal): animal is Bird => {
let res_ = (animal as Bird).feathersColor !== undefined;
return res_;
}
const parrot: Animal = {name: "Parrot", feathersColor: "green"};
const oscar: Animal = {name: "Oscar", finsColor: "orange"};
//first call with a bird
console.log(isBird(parrot))
//second call with a fish
console.log(isBird(oscar))