타입 가드
Typescript에서 변수의 타입을 좁히는데 사용되는 메커니즘
사용자 정의 타입가드
타입 서술어 사용
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
- 보통 타입 가드는 isFish 와 같이 is를 많이 붙인다.
- is 는 타입 가드에서 사용되는 키워드이다.
- pet is Fish 파라미터(pet)가 실재 해당 타입(Fish)인지 구분하는 키워드이다.
- return (target as Developer).swim !== undefined 는 pet에 swim 프로퍼티가 있으면 Fish 타입으로 취급한다.
interface Bird {
fly: () => void;
layEggs: () => void;
}
interface Fish {
swim: () => void;
layEggs: () => void;
}
function getSmallPet(): Fish | Bird {
return {
fly: function() {},
layEggs: function() {}
};
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
let pet = getSmallPet();
if(isFish(pet)) {
pet.swim(); // Fish
} else {
pet.fly(); // Bird
}
pet 이 if 문 안에서 Fish 라는 것을 알고 있고, else 문 안에서는 Fish 타입이 아니라는 걸 알고 있으므로 Bird 를 반드시 가지고 있다.
in연산자 사용
in 연산자는 타입을 좁히는 표현으로 작용
n in x 표현에서 n은 문자열 혹은 리터럴 타입이고, x 는 유니언 타입
function move(pet: Fish | Bird) {
if('swim' in pet) {
return pet.swim();
}
return pet.fly();
}
typeof 타입가드
값이 원시 타입인지 아닌지 확인하는 함수를 정의할 수 있다.
function isNumber(x: any): x is number {
return typeof x === "number";
}
function isString(x: any): x is string {
return typeof x === "string";
}
그러나 원시타입 확인을 위해 모든 함수를 작성하는 건 번거로운 일이다. 다행인 사실은, 타입스크립트는 typeof를 타입가드로 인식한다.
function valueFunc(value: number | string) {
// typeof 타입 가드로 사용할 수 있다.
if(typeof value === 'string') {
return value.length; // string
}
return value; // number
}
instanceof 타입 가드
생성자 함수를 사용해 타입을 좁힐 수 있다.
interface Person {
// name: string;
getName: () => string;
}
class Employee implements Person {
constructor(private name: string) { }
getName() {
return this.name;
}
}
class Employer implements Person {
constructor(private name: string) { }
getName() {
return this.name;
}
}
function getClass(isEmployee: boolean = true) {
return isEmployee ?
new Employee('Employee')
: new Employer('Employer');
}
let person: Person = getClass(true);
if(person instanceof Employee) {
person; // person 타입은 Employee
}
if(person instanceof Employer) {
person; // person 타입은 Employer
}
널러블 타입
타입스크립트에서 null과 undefined는 모든 타입에서 유효한 값이다. 즉, 방지하고 싶어도 어떤 타입에 할당되는 것을 방지할 수 없다.
이 문제는 --strictNullChecks플래그로 해결 가능하다. 변수를 선언할 시에 자동으로 null이나 undefined를 포함하지 않고, 유니온 타입을 사용해 명시적으로 포함할 수 있다.
// --strictNullChecks 플래그로 null을 포함하지 못하게 한다.
let str = "str";
str = null; // 오류
// 유니온 타입을 사용해서 명시적으로 null을 포함한다.
let str2: string | null = "atr2";
str2 = null;
선택적 매개변수 & 프로퍼티
--strictNullChecks를 적용할 때 선택적 매개변수에 | undefined를 자동으로 추가한다.
// 선택적 매개변수
function fun(x: number, y?: number) {
return x + (y || 0);
}
fun(1, 2);
fun(1);
fun(1, undefined); // | undefined가 자동으로 추가되므로 오류가 발생하지 않는다.
fun(1, null); // 오류, 'null' 은 number | undefined에 할당할 수 없다.
// 선택적 프로퍼티도 마찬가지
class C {
a: number;
b?: number;
}
let c = new C();
c.a = 1;
c.b = 2;
c.b = undefined; // | undefined가 자동으로 추가되므로 오류가 발생하지 않는다.
c.b = null; // 오류, 'null' 은 number | undefined에 할당할 수 없다.
'JavaScript' 카테고리의 다른 글
CSV 파일을 JSON으로 만들어서 활용하기 (0) | 2023.11.01 |
---|---|
[JS] 엄격 모드(Strict Mode) (2) | 2023.08.30 |
[Node.js] node-cron을 사용해서 일정 시간 마다 특정 작업해주기 (0) | 2023.06.29 |
lodash debounce를 활용하여 성능 향상시키기 (0) | 2023.06.03 |
[JS] 비동기 깊이 알아보기 :블로킹 vs 논 블로킹, async/await과 Promise (2) | 2023.04.06 |