엄격 모드 | 비엄격 모드 | |
---|---|---|
함수 리턴 타입 | 공변적 | 공변적 |
함수 파라미터 타입 | 반공변적 | 이변적 |
그 외 | 공변적 | 공변적 |
strictFunctionTypes
옵션을 껐을 때 함수 파라미터 동작공변성 :
A
가B
의 서브 타입이면,T<A>
는T<B>
의 서브 타입
아래 예시에서 superArray
(string | number
)는 subArray
(string
)보다 넓은 타입을 가진다. 따라서 string
은 string | number
에 포함되는 서브 타입이고, string | number
는 string
을 포함하는 슈퍼 타입이다.
좁은 타입인 subArray
를 넓은 타입인 superArray
에 대입하는건 문제가 발생하지 않는다. 반면 넓은 타입을 좁은 타입에 대입할 땐 에러가 발생한다.
let superArray: Array<string | number> = [];
let subArray: Array<string> = [];
superArray = subArray; // OK
subArray = superArray; // Error 'number' 형식은 'string' 형식에 할당할 수 없습니다(ts2322)
이처럼 좁은 타입을 넓은 타입에 대입 할 수 있는 동작을 공변성(Covariance; 协方差)이라고 부른다. 타입스크립트는 기본적으로 공변성을 갖는다.
함수의 리턴 타입 역시 공변성을 가진다. a
의 리턴 타입(number
)이 B
의 리턴 타입(number | string
)보다 좁은 타입이므로, a
를 b
에 대입해도 문제가 발생하지 않는다.
function a(x: string): number { return 0; }
type B = (x: string) => number | string;
const b: B = a; // OK (a 리턴 타입 < B 리턴 타입)
반대로 a
리턴 타입이 더 넓은 타입을 갖도록 변경하면 에러가 발생한다.
function a(x: string): number | string { return 0; }
type B = (x: string) => number;
const b: B = a; // Error (a 리턴 타입 > B 리턴 타입)
<aside>
💡 함수 파라미터는 strictFunctionTypes
옵션을 켰을 땐(true
) 반공변성을, 해당 옵션을 껐을 땐(false
) 이변성을 가진다. strictFunctionTypes
옵션의 기본값은 true
이다.
</aside>
반공변성 :
A
가B
의 서브 타입이면,T<B>
는T<A>
의 서브 타입