<aside> 💡

타입 간의 포함관계를 나타낼 때 사용한다. 기본적으로 타입스크립트는 공변성을 가지고 있지만, 함수의 매개변수는 반공변성을 갖고 있다.

</aside>

공변성

// string | number가 string보다 더 넓은 타입이므로
// <string | number>에 <string>을 할당 가능
function a(x: string): string {
    return ''
}
type B = (x: string) => string | number
const b: B = a

그 반대는 공변성에 위배된다.

function c(x: string): string | number {
    return ''
}
type D = (x: string) => string
const d: D = c
     ^^^ 
  // Type '(x: string) => string | number' is not assignable to type 'D'.
  // Type 'string | number' is not assignable to type 'string'.

반공변성

하지만 함수의 매개변수의 경우에는 반공변성이 성립한다.

// string | number가 string보다 넓은 타입이므로
// 아래의 경우에는 반공변성에 의해 할당이 불가능하다

function a(x: string): string {
    return ''
}
type B = (x: string | number) => string
const b: B = a
     ^^^
  // Type '(x: string) => string' is not assignable to type 'B'.
  // Types of parameters 'x' and 'x' are incompatible.
  // Type 'string | number' is not assignable to type 'string'.
  // Type 'number' is not assignable to type 'string'.

이런 경우 성립한다

function c(x: string | number): string {
    return ''
}
type D = (x: string) => string
const d: D = c

함수의 매개변수에서 반공변성이 성립하는 이유는