interface Item {
name: string;
x: number;
y: number;
}
interface SuperItem extends Item {
z: number;
}
const item: Item = { name: 'name', x: 0, y: 0 };
const superItem: SuperItem = {...item, z: 0 };
function printItemKeys (item: Item) {
const itemKeys = Object.keys(item);
/*
우리가 예상한 것은 name, x, y 가 console에 출력되는 것이지만
아래 printItemKeys 함수 실행부에 어떤 object를 인자로 넣어주냐에 따라 name, x, y ,z 가 출력되는 경우도 존재한다.
*/
itemKeys.forEach((key) => console.log(key));
}
// 'name', 'x', 'y'
printItemKeys(item);
// 함수 선언부에서 예측한 결과와 다른 결과가 나타나는 함수 실행부
// 'name', 'x', 'y', 'z'
printItemKeys(superItem);
이런 상황에서 itemKeys는 우리가 생각한 대로라면 ['name', 'x', 'y'] 가 되어야 하지만
printItemKeys(superItem)
이 경우에는 ['name', 'x', 'y', 'z'] 가 된다.
즉 타입스크립트는 구조적 타입 시스템으로 동작하기 때문에 정확히 일치하는 상속의 개념보다 포함하는 집합의 개념에 더 가깝다. 슈퍼셋의 타입을 허용하게 되는 것이다.
구조적 타입 시스템으로 인한 슈퍼셋이 들어올 경우를 대비해야하기 때문에 가 아닌 단순히 string 으로 타입을 지정해준 것으로 보인다.
구조적 타입 시스템이 무엇인지에 대해서는 구조적 타이핑이란? 포스팅을 참고
아주 중요한 정보를 얻었습니다, 감사합니다.