티스토리 뷰
🍫 함수 타입의 호환성
특정 함수 타입을 다른 함수 타입으로 괜찮은지 판단하는 것
타입 호환성을 판단하는 기준 2가지를 모두 만족해야만 함수 타입 호환성이 가능하다.
- 두 함수의 반환값 타입이 호환되는가?
- 두 함수의 매개변수의 타입이 호환되는가?
기준 1. 반환값 타입이 호환되는가?
type A = () => number;
type B = () => 10;
let a:A = () => 10;
let b:B = () => 10;
a = b;
// number타입은 number literal 타입의 슈퍼 타입으로 다운 캐스팅 불가능
b = a; // ❌
// 즉, 반환값끼리의 다운 캐스팅이 되면 안됨
타입 A의 반환값은 number, 타입 B의 반환값은 number literal으로 A 반환값 타입이 B 반환값 타입의 슈퍼 타입이다. 따라서 변수 a에 b를 할당하는 것은 가능하지만 그 반대는 다운 캐스팅이므로 불가능하다.
기준2. 매개변수의 타입이 호환되는가?
두 함수의 매개변수의 개수가 같은지 다른지에 따라 두 가지 유형으로 나뉜다.
2-1. 매개변수의 개수가 같을 때
매개변수의 개수가 같을 때, 업캐스팅의 경우 호환이 불가능하다고 판단한다.
type C = (value: number) => void;
type D = (value: 10) => void;
let c:C = (value) => {};
let d:D = (value) => {};
// number literal 타입을 number 타입으로 업캐스팅이 왜 불가능?
// -> 매개변수의 타입을 기준으로 호환성을 판단할때는 업캐스팅의 경우 호환이 불가능하다고 평가
c = d; // ❌
d = c;
함수 c와 함수 d는 각각 number타입의 매개변수와 number literal 타입의 매개변수를 받는다. 따라서 c 매개변수의 타입이 d 매개변수의 슈퍼타입이므로 d를 c로 취급하는 것은 불가능하다.
이는 반환값 타입과 반대되는, 다운 캐스팅을 허용하는 것과 같아 보인다.
📍 매개변수가 객체 타입을 사용하는 예시
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);
};
Animal 타입은 Dog 타입보다 프로퍼티가 적기 때문에 Dog 타입의 슈퍼 타입이다.
이때 어떤 타입이 호환되는지 알아보자.
animalFunc = dogFunc; // ❌
// 위 식을 표현해본다면
// 타입은 Animal 타입을 따르고
// 출력은 dogFunc의 본문을 따름
let testFunc = (animal:Animal) => {
console.log(animal.name);
console.log(animal.color);
}
dogFunc = animalFunc;
// 타입은 Dog 타입을 따르고
// 출력은 animalFunc의 본문을 따름
let testFunc2 = (dog:Dog) => {
console.log(dog.name);
}
testFunc는 Animal 타입을 따르는 매개변수를 받아오지만 본문은 dogFunc의 본문을 따른다. 때문에 animal의 color 프로퍼티는 존재하지 않아 오류가 발생한다. 반대로 testFunc2의 경우, Dog 타입을 따르는 매개변수를 받아와 animalFunc의 본문을 따라도 Animal 타입이 Dog 타입의 슈퍼타입이기 때문에 dog의 name 프로퍼티가 존재해 오류가 발생하지 않아 호환이 가능하다.
따라서 두 개의 함수 타입 A와 B가 있을 때 두 매개변수의 개수가 같을 경우 B를 A로 취급하기 위해서는 A 매개변수의 타입이 B 매개변수 타입의 서브 타입이어야 한다.
2-2. 매개변수의 개수가 다를 때
단, 타입은 같아야한다.
type Func1 = (a:number, b:number) => void;
type Func2 = (a:number) => void;
let func1:Func1 = (a,b) => {};
let func2:Func2 = (a) => {};
// Func1 타입을 Func2 타입으로 취급
func1 = func2;
// 할당하려는 쪽의 매개변수의 개수가 더 많은 쪽이면 호환 안됨
func2 = func1;
매개변수의 개수가 다를 때, 할당하려는 쪽의 매개변수의 개수가 더 많은 쪽이면 호환이 되지 않는다.
'코딩 > 한 입 크기로 잘라먹는 타입스크립트' 카테고리의 다른 글
[TypeScript] 사용자 정의 타입가드 (0) | 2023.09.04 |
---|---|
[TypeScript] 함수 오버로딩 (0) | 2023.09.02 |
[TypeScript] 함수 타입 표현식과 호출 시그니쳐 (0) | 2023.08.28 |
[TypeScript] 함수 타입 (0) | 2023.08.25 |
[TypeScript] 서로소 유니온 타입 (0) | 2023.08.23 |