
최근 업데이트 24.03.16
💡 서브타이핑
서브타이핑은 다형성의 한 형태로, '서브 타입'이 '베이스 타입'과
어떤 형태의 '대체 가능성'에 의해 연결되는 것인지 의미한다
'대체 가능성'은 '베이스 타입'의 변수가 '서브 타입' 값도 받아 들일 수 있음을 의미
가장 핵심은
공변성(Covariance) : A가 B의 서브타입이면,
T<A>는T<B>의 서브타입이다.
반공변성(Contravariance) : A가 B의 서브타입이면,T<B>는T<A>의 서브타입이다.
let stringArray: Array<string> = [];
let array: Array<string | number> = [];
array = stringArray; // OK - stringArray는 array를 포함
stringArray = array; // Error
// --------------------------------------------------
let subObj: { a: string; b: number } = { a: '1', b: 1 };
let superObj: { a: string | number; b: number } = subObj; // superObj는 subObj 포함
// subObj <: superObj
// 각각의 프로퍼티가 대응하는 프로퍼티와 같거나 서브타입이어야 한다.
T<A> 가 T<B> 의 서브타입이 된다면, T를 공변적이라고 부를 수 있다.function a (x:string) {
return +x
}
a('1') // 1
type B = (x: string) => number | string
const b: B = a
type Logger<T> = (param: T) => void;
let logNumber: Logger<number> = (param) => {
console.log(param); // number
};
let log: Logger<string | number> = (param) => {
console.log(param); // string | number
};
logNumber = log; // OK
log = logNumber; // Error
// 기본적으로 number <: string | number 지만, 함수 매개변수 제네릭에서는 거꾸로
// Logger<string | number> <: Logger<number>
위의 코드를 보면 인자로 string | number 를 받는 log 함수와, 인자로 number 만을 받는 logNumber 함수가 있다.
원래라면, 공변성의 규칙에 따르면, log 함수는 넓은 타입이고, logNumber는 좁은 타입이니, log = logNumber 식은 성립되야 하지만 에러가 발생한다.
함수의 매개변수의 타입을 다룰경우 반공변성으로 따르기 때문이다.
따라서 logNumber = log 가 성립 된다.
function a (x: string | number) {
return +x
}
type B = (x: string) => number
let b: B = a
함수의 리턴 타입
좁은 타입을 넓은 타입에 넣기함수의 파라미터 타입
넓은 타입을 좁은 타입에 넣기타입스크립트는 기본적으로 공변적으로 동작하나, 타입스크립트의 파라미터는 반공변적으로 동작한다