해결된 질문
작성
·
47
0
안녕하세요, 함수타입의 호환성에 대해 궁금한게 생겨 질문드립니다.
type Animal = {
name: string;
color: string;
};
type Dog = {
name: string;
color: string;
breed: string;
};
let animal: Animal = {
name: "기린",
color: "yellow",
};
let dog: Dog = {
name: "돌돌이",
color: "brown",
breed: "진도",
};
animal = dog; // ✅ OK
dog = animal; // ❌ NO
이전 강의인 '타입스크립트 이해하기>객체 타입의 호환성' 에서는 위 코드에서 animal=dog는 가능하지만 dog=animal은 안된다고 하셨습니다. dog가 animal의 서브타입이기에 '수퍼를 서브에 넣을 순 없다' 라는 개념까지는 이해했습니다.
그런데 오늘 강의에서는 비슷한 코드인데 dogFunc을 animalFunc에 넣을 수 없다고 한 것이 이해되지 않습니다. dog가 animal의 서브인건 여전한데 왜 이 경우엔 안되는건가요?
type Animal = {
name: string;
};
type Dog = {
name: string;
color: string;
};
let animalFunc = (animal: Animal) => {
console.log(animal.name);
};
let dogFunc = (dog: Dog) => {
console.log(dog.name);
console.log(dog.color);
};
animalFunc = dogFunc; // ❌
dogFunc = animalFunc; // ✅
답변 2
0
안녕하세요 이정환입니다.
타입스크립트에서 함수 타입의 호환성을 평가하면서 매개변수 간의 호환을 판단할 때에는 아주 특별하게 다운 캐스팅이 허용되고, 업 캐스팅은 허용되지 않습니다.
이렇게 되는 이유는 A, B 두 함수가 있을 때 "A 매개변수" 타입이 "B 매개변수" 타입의 슈퍼타입이라면 A 함수는 B 함수의 서브 타입이 되기 때문입니다. 반대로 "A 매개변수" 타입이 "B 매개변수" 타입의 서브 타입이라면 A 함수는 B 함수의 슈퍼타입이 됩니다.
쉽게 말하자면 두 함수 타입간의 관계는 매개변수가 서브타입인 쪽이 슈퍼타입이 된다고 이해하시면 됩니다.
그 이유에 대해서는 코드와 함께 설명드리도록 하겠습니다. 아래의 두 코드를
type Animal = {
name: string;
};
type Dog = {
name: string;
color: string;
};
let animalFunc = (animal: Animal) => {
console.log(animal.name);
};
let dogFunc = (dog: Dog) => {
console.log(dog.name);
console.log(dog.color);
};
animalFunc = dogFunc; // ❌ ①
dogFunc = animalFunc; // ✅
위 코드를 살펴보면 Animal 타입의 매개변수를 받는 animalFunc 함수의 타입은 (value : Animal) => void
가 됩니다. 반면 Dog 타입의 매개변수를 받는 dogFunc 함수의 타입은 (value: Dog) => void
가 되겠죠?
이때 ①에서 (value : Animal) => void
타입의 변수 animalFunc에 (value: Dog) => void
타입의 값을 할당하려고 하면 오류가 발생하는데요 그 이유에 대해 천천히 살펴보겠습니다.
우선 이 할당식은 dogFunc 함수 타입의 값을, animalFunc 함수 타입의 값으로 취급하는 것입니다. dogFunc 함수 타입의 값을 animalFunc 함수 타입의 변수에 할당하고 있으니까요 위 내용을 코드로 표현하면 다음과 같습니다.
type AnimalFunc = (value: Animal) => void;
let dogFunc: AnimalFunc = (dog: Dog) => { // 타입 오류 발생
console.log(dog.name);
console.log(dog.color);
};
그러나 이는 오류로 평가됩니다. 그 이유는 Animal 타입의 매개변수에는 color 등의 프로퍼티가 없는데, 함수 내부에서는 Dog 타입의 매개변수가 제공될 것을 예상하고 color 등의 Dog 타입에만 존재하는 프로퍼티를 사용하고 있기 때문입니다.
이처럼 타입스크립트에서 함수 타입간의 호환성을 평가할 때에는 매개변수의 타입은 오히려 다운 캐스팅이 허용되는 방향으로 예외적으로 동작한다고 이해하시면 됩니다. 자세한 이유에 대해서는 공변/반공변 개념에 대해 추가적으로 살펴보시면 도움이 될 듯 합니다.
혹시 이해가 잘 안되신다면 답글 주세요!
0
안녕하세요, 인프런 AI 인턴입니다. 민수연님.
함수 타입의 호환성에 대해 질문해 주셨군요. 타입스크립트에서의 함수 타입 호환성은 일반 객체 타입의 호환성과 달리, 매개변수의 관계와 반환 값까지도 고려됩니다. 이를 이해하기 위해 함수의 매개변수와 반환값이 어떻게 호환되는지를 살펴보겠습니다.
매개변수의 설정:
dogFunc
의 매개변수는 Dog
타입으로 name
과 color
가 필요합니다. 이 함수에 Animal
만 받는 animalFunc
을 대체할 수 없습니다, 왜냐하면 dogFunc
는 추가적인 color
프로퍼티가 필요하기 때문입니다.반환값의 설정:
따라서, 주어진 코드에서:
- animalFunc = dogFunc;
는 불가능합니다. animalFunc
은 name
만 처리할 수 있지만 dogFunc
은 color
도 처리하려고 하기 때문에 함수의 매개변수 조건을 충족하지 못해 대입이 불가능합니다.
- dogFunc = animalFunc;
는 가능합니다. dogFunc
의 요구사항보다 적은 요구사항을 가지기 때문에 문제되지 않습니다.
함수형 프로그래밍에서 자주 말하는 런타임 오류를 방지하기 위해 타입스크립트는 이러한 호환성을 철저히 검사합니다.
관련 질문 URL:
- 함수 타입의 호환성에 대해서 궁금한 사항이 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
이해 됐습니다! 감사합니다 :-)