Typescript의 타입 호환성
> 구조적 서브타이핑 기반
구조적 서브타이핑
> 오직 멤버만으로 타입을 관계시키는 방식
> y가 최소환 x와 동일한 멤버를 가지고 있다면, x와 y는 호환된다.
> '덕 타이핑'이라고도 함 '만약 어떤 새가 오리처럼 걷고, 헤엄치고, 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를것이다'
type Food = {
/** 각 영양소에 대한 gram 중량값 */
protein: number;
carbohydrates: number;
fat: number;
}
type Burger = Food & {
/** 햄버거 브랜드 이름 */
burgerBrand: string;
}
function calculateCalorie(food: Food) {
return food.protein * 4
+ food.carbohydrates * 4
+ food.fat * 9
}
const burger: Burger = {
protein: 29,
carbohydrates: 48,
fat: 13,
burgerBrand: '버거킹'
}
const calorie = calculateCalorie(burger)
/** 타입검사결과 : 오류없음 (OK) */
fresh object를 직접 calculateCalorie() 함수에 넣으면 컴파일 에러 발생
> typescript에서 컴파일할 때 FreshLiteral 여부를 확인. Fresh하다면 컴파일 에러 발생
> type assertion하거나 타입추론에 의해 타입이 확정되면 freshness 사라짐
> 이렇게 하는 이유는 코드를 읽는 다른 개발자의 입장에서 함수가 실제 다루는 것보다 더 많은 데이터를 받아들인다는 오해를 불어일으킬 수 있고, 프로퍼티 키에 대한 오타가 발생하더라도 오류가 확인되지 않는 부작용 때문
> 그럼에도 불구하고 fresh object를 사용하고 싶다면 tsconfig에서 suppressExcessPropertyErrors: true로 변경
const calorie = calculateCalorie({
protein: 29,
carbohydrates: 48,
fat: 13,
burgerBrand: '버거킹'
})
/** 타임검사결과 : 오류 (NOT OK)*/
/** 부작용 1
* 코드를 읽는 다른 개발자가 calculateCalorie 함수가
* burgerBrand를 사용한다고 오해할 수 있음 */
const calorie1 = calculateCalorie({
protein: 29,
carbohydrates: 48,
fat: 13,
burgerBrand: '버거킹'
})
/** 부작용 2
* birgerBrand 라는 오타가 발생하더라도
* excess property이기 때문에 호환에 의해 오류가
* 발견되지 않음 */
const calorie2 = calculateCalorie({
protein: 29,
carbohydrates: 48,
fat: 13,
birgerBrand: '버거킹'
})
반대로 타입 호환을 허용하지 않도록 강제하는 것도 가능
https://toss.tech/article/typescript-type-compatibility
TypeScript 타입 시스템 뜯어보기: 타입 호환성
타입호환성은 무엇이며 왜 필요할까요? 타입호환이 지원되지 않는 경우가 존재한다는 것을 아셨나요? 평소 익숙했던 개념들에 대해 질문을 던져가며 TypeScript 타입 시스템에 관해 심도있게 알아
toss.tech
'IT > typescript' 카테고리의 다른 글
[Typescript] Type-Only Imports and Export (0) | 2024.03.08 |
---|---|
[Typescript] satisfies (0) | 2024.02.22 |
[Typescript] Branded type (0) | 2024.02.21 |
[Typescript] asserts를 이용한 타입 가드 활용 (0) | 2024.02.05 |
[Typescript] 외부 패키지의 타입 치환 (1) | 2024.02.05 |