[Typescript] 공변성과 반공변성

채동기·2023년 3월 20일
0

TypeScript

목록 보기
17/21

기본적으로 타입스크립트에서는 공변성을 갖고 있지만, 함수의 매개변수는 반공변성을 갖고 있습니다

- 공변성: A->B일 때 T<A> -> T<B>인 경우 (좁은 타입을 넓은 타입에 대입할 수 있는 것)
- 반공변성: A->B일 때 T<B> -> T<A>인 경우 (넓은 타입을 좁은 타입에 대입할 수 있는 것)
- 이변성(Bivariance) : A가 B의 서브타입이면, T<A> → T<B>도 되고 T<B> → T<A>도 되는 경우
- 불변성(immutability) : A가 B의 서브타입이더라도, T<A> → T<B>도 안 되고 T<B> → T<A>도 안 되는 경우

반환값은 공변성을 띄지만, 매개변수는 반공명성을 띕니다.

공변성

A(좁은 타입)가 B(넓은 타입)의 서브타입이면, T<A>는 T<B>의 서브타입이다.
A ⊂ B → T<A> ⊂ T<B>
function a(x: string): number {
  return 0;
}

type B = (x: string) => number | string;

let b: B = a;

반공변성

A(좁은 타입)가 B(넓은 타입)의 서브타입이면, T<B>는 T<A>의 서브타입이다.
A ⊂ B → T<B> ⊂ T<A>
그런데 위의 공변성 규칙이 함수의 매개변수로 전달된 경우, 이것이 반대로 동작한다.
function a(x: string | number): number {
  return 0;
}

type B = (x: string) => number;

let b: B = a;

반공변성이 되는 이유는 에러를 막기 위한 것 같습니다.

B = (x: string) => {
  a = (x: string | number) => {

  }
}

위의 코드는 에러가 발생하지 않지만,

a = (x: string | number) => {
  B = (x: string ) => {

  }
}

위의 코드에서는 에러가 발생할 수 있습니다.
왜냐하면, number 타입이 들어오면 함수 B에서 number를 처리할 수 없기 때문입니다.

참조

https://www.zerocho.com/category/TypeScript/post/5faa8c657753bd00048a27d8
https://inpa.tistory.com/entry/TS-%F0%9F%93%98-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B3%B5%EB%B3%80%EC%84%B1-%EB%B0%98%EA%B3%B5%EB%B3%80%EC%84%B1-%F0%9F%92%A1-%ED%95%B5%EC%8B%AC-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0

profile
what doesn't kill you makes you stronger

0개의 댓글