함수 타입의 호환성
함수 타입의 호환성이란, '특정 함수 타입을 다른 함수 타입으로 취급해도 괜찮은가' 를 판단하는 기준을 말한다.
두 가지 기준을 만족해야만, 두 함수의 타입이 호환된다고 말할 수 있다.
type A = () => number;
type B = () => 10;
let a: A = () => 10; // number
let b: B = () => 10; // number literal
a = b; // ✅ 업 캐스팅 (하위 타입 → 상위 타입) 허용
b = a; // ❌ 오류 발생 (상위 타입 → 하위 타입)
number literal → number 업 캐스팅은 허용되지만,number → number literal 다운 캐스팅은 허용되지 않는다.type C = (value: number) => void;
type D = (value: number) => void;
let c: C = (value) => {};
let d: D = (value) => {};
c = d;
d = c; // ✅ 동일한 매개변수 타입이므로 문제 없음
type C = (value: number) => void;
type D = (value: 10) => void;
let c: C = (value) => {};
let d: D = (value) => {};
c = d; // ❌ 오류 발생 (업 캐스팅 불가)
d = c; // ✅ 다운 캐스팅 허용
// Animal 타입은 Dog 타입의 슈퍼 타입이다.
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; // ✅ 다운 캐스팅 가능
dogFunc는 color 속성을 기대하지만, animalFunc는 color 속성을 제공하지 않기 때문에 업 캐스팅이 불가능하다.type Func1 = (a: number, b: number) => void;
type Func2 = (a: number) => void;
let func1: Func1 = (a, b) => {};
let func2: Func2 = (a) => {};
func1 = func2; // ✅ 허용
func2 = func1; // ❌ 오류 발생
function useCallback(callback: (value: number, index: number) => void) {
callback(10, 1);
}
let myCallback = (value: number) => {
console.log(value);
};
useCallback(myCallback); // ✅ 허용
myCallback은 index 매개변수를 무시하지만, 호출에는 영향을 주지 않으므로 안전하다.| 기준 | 허용 여부 |
|---|---|
| 반환 값: 하위 타입 → 상위 타입 (업 캐스팅) | ✅ 가능 |
| 반환 값: 상위 타입 → 하위 타입 (다운 캐스팅) | ❌ 불가능 |
| 매개변수: 상위 타입 → 하위 타입 (다운 캐스팅) | ✅ 가능 |
| 매개변수: 하위 타입 → 상위 타입 (업 캐스팅) | ❌ 불가능 |
| 매개변수 개수: 더 적은 매개변수를 갖는 함수 할당 | ✅ 가능 |
| 매개변수 개수: 더 많은 매개변수를 갖는 함수 할당 | ❌ 불가능 |