
구조적 타이핑(structural typing)
자바스크립트는 덕 타이핑 기반이고 타입스크립트는 자바스크립트를 모델링하기 위해 구조적 타이핑을 사용한다.
타입스크립트의 구조적 타이핑을 이야기하려면 먼저 덕 타이핑을 알아야 한다.
덕 타이핑
덕 타이핑을 설명하기 위해 극단적인 예시를 들자면
어떤 새가 오리처럼 울고, 오리처럼 날면 오리라고 생각하는 것이다. 발이 3개더라도
구조적 타이핑 예시
구조적 타이핑은 구조와 정의에 따라 결정되는 타입 시스템인데, 요약하면 덕 타이핑으로 이해해도 된다.
어떤 새가 오리처럼 울고, 오리처럼 날면 오리라고 생각하는 것이다.
발이 3개더라도
위 문장을 생각한채로 아래 코드를 보자.
interface NormalBirdType {
sound: string;
wings: string;
}
const isNormalBird = (bird: NormalBirdType) => {
console.log(bird.sound.length > 0 && bird.wings.length > 0);
return bird.sound.length > 0 && bird.wings.length > 0;
};
const bird1 = { sound: "꽦꼬ㅒㄲ", wings: "하얀색이고 2개" };
isNormalBird(bird1); // true
const bird3legs = { sound: "꽦꼬ㅒㄲ", wings: "하얀색이고 2개", legs: 3 };
// legs는 신경쓰지 않음.
isNormalBird(bird3legs); // true
어떤 새가 오리처럼 울고, 오리처럼 날면 오리라고 본다. 발이 3개라도
bird3legs의 속성중에 sound: string, wings: string 를 만족하면 NormalBirdType으로 본다. legs의 속성과는 무관하게
구조적 타이핑 관점에서 sound와 wings가 있기 때문에 bird3legs는 NormalBirdType과 호환되어 hiBird의 매개변수로 사용할 수 있다.
=> 즉, 기대하는 속성만 만족을 하면 더 많은 속성을 사용해도 문제가 되지 않는다.
구조적 타이핑 문제점
위 예시에서 구조적 타이핑에 의해 sound와 wings만 만족하면 외부의 다른 속성은 고려하지 않게 된다.
아래 코드에서 legs는 타입 체커가 문제로 인식하지 않는다.
interface NormalBirdType {
sound: string;
wings: string;
}
const isNormalBird = (bird: NormalBirdType) => {
console.log(bird.sound.length > 0 && bird.wings.length > 0);
return bird.sound.length > 0 && bird.wings.length > 0;
};
const bird3legs = { sound: "꽦꼬ㅒㄲ", wings: "하얀색이고 2개", legs: 3 };
// true이면 안되는데 true임
const 날개_빼면_다리만_두개_남는가 = isNormalBird(bird3legs);
날개_빼면_다리만_두개_남는가
에서 isNormalBird(bird3legs)는 false를 반환해야 하지만 하지만 true를 반환한다.
이를 해결하기 위해서는 런타임에서의 타입체크나 명시적인 타입체크가 필요하다.(타입스크립트는 런타임에서 사라진다)
const isNormalBird = (bird: NormalBirdType) => {
const allowedKeys = ["sound", "wings"];
// sound,wings외에도 다른 속성이 있으면 return false
for (const key in bird) {
if (!allowedKeys.includes(key)) {
return false;
}
}
return bird.sound.length > 0 && bird.wings.length > 0;
};
const bird3legs = { sound: "꽦꼬ㅒㄲ", wings: "하얀색이고 2개", legs: 3 };
isNormalBird(bird3legs);
const 날개_빼면_다리만_두개_남는가 = isNormalBird(bird3legs); // false
'개발 > TypeScript' 카테고리의 다른 글
ts-ignore와 ts-expect-error로 ts에러 지울 수 있음.(next13 임시방편) (0) | 2023.10.11 |
---|---|
잉여타입검사와 덕타이핑 (0) | 2023.09.02 |
타입 단언할때 unknown이 나타나는 이유 (0) | 2023.09.02 |
Exclude (0) | 2023.06.05 |
실제 작동하는 Javascript를 무겁게 만드는 enum과 그 대안 : as const를 활용한 객체 (0) | 2023.02.19 |