1. 사용자 정의 타입가드 (User-Defined Type Guard)
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function introduce(): Developer | Person {
return {
name: 'Tony',
age: 33,
skill: 'Iron Making',
};
}
let tony = introduce();
function isDeveloper(target: Developer | Person): target is Developer {
return (target as Developer).skill !== undefined;
}
if (isDeveloper(tony)) {
tony.skill;
} else {
tony.age;
}
- 타입 가드 패턴 중 많이 사용하는 패턴 중 하나
- 함수 이름은 is해당타입 처럼 is를 붙이고, 해당 타입인지 아닌지를 나타내는 함수를 작성
- 파라미터(target)로 타입들을 유니언 타입으로 동일하게 받을 수 있게 함
- is 키워드 : 넘겨받은 파라미터가 해당 타입인지를 반환
- 반환값을 as 키워드를 사용하여 해당 타입으로 가정하고, 해당 타입만의 속성이 있다면 해당 타입이라고 취급
- is 로직을 통과하면 해당 타입인지 아닌지 구분을 해주므로, 조건문을 통해 제공되는 속성값을 다르게 함
- 타입가드를 정의하고 로직을 통해 boolean 값을 반환하여 해당 타입인지 구분을 함
- 해당 타입이라면 속성에 접근을 하고, 아니라면 다른 타입의 속성에 접근할 수 있게 해줌
- 각각의 필요한 속성에 접근할 수 있는 타입가드를 이용한 타입 구분 방식
2. 타입 호환 (Type Compatibility)
interface Person {
name: string;
}
class Developer {
name: string;
}
let i: Person;
i = new Developer();
- 타입 호환 : 타입스크립트 코드에서 특정 타입이 잘 맞는지를 의미, 타입스크립트가 코드를 해석해나가는 과정에서 두 개의 타입이 서로 호환이 되는지를 점검하는 것
- 타입스크립트 관점에서는 타입이 정의되어있는 속성을 갖고 타입이 호환되는 지를 점검
- 구조적 타이핑 : 코드 구조 관점에서 타입이 호환되는지 여부 판단
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
}
let developer: Developer;
let person: Person;
person = developer
developer = person;
- 오른쪽 타입이 왼쪽 타입에 호환되려면 더 많은 속성을 갖거나 구조적으로 더 커야함
- 구조적으로 더 큰 타입에서는 더 작은 타입을 지원할 수 없음
- 항상 타입이 맞지 않아도 구조적으로 내부에 존재하고 있는 속성과 타입에 대한 정의들에 대해서만 비교를 함
let add = (a: number) => {
};
let sum = (a: number, b: number) => {
};
sum = add;
add = sum;
- 함수는 파라미터의 타입이 많은 쪽이 구조적으로 크고, 왼쪽에 있어야 함
- 함수 내부적으로 파라미터 혹은 반환값이 더 많거나 많은 타입들을 가져가면 그 함수는 구조적으로 큼
- 더 넓은 범위의 함수가 더 작은 범위의 함수를 호환할 수 있음
interface Empty<T> {}
let empty1: Empty<string>;
let empty2: Empty<number>;
empty1 = empty2;
empty2 = empty1;
interface NotEmpty<T> {
data: T;
}
let notempty1: NotEmpty<string>;
let notempty2: NotEmpty<number>;
notempty1 = notempty2;
notempty2 = notempty1;
- 구조적으로 비어있으면 어떠한 값이 들어가더라도 서로 동일한 타입이라고 간주하고, 호환이 됨
- 구조적으로 제네릭에 의해 값이 바뀐다고 하면, 구조적인 타입의 차이가 생김
- 즉, 동일한 속성은 있지만 타입은 달라지므로 서로 호환이 되지 않음
참고 : 타입스크립트 입문 - 기초부터 실전까지