공변성 :A -> B 일 때, T<A> -> T<B>
반공변성 : A -> B 일 때 T<B> -> T<A>
이변성 : A -> B 일 때 T<A> -> T<B> 됨 T<B> -> T<A> 됨
무변성 : A -> B 일 때 T<A> -> T<B> 도 안되고 T<B> -> T<A> 도 안됨
기본적으로 타입스크립트는 공변성의 갖고 있음
근데 함수의 매개변수는 반공변성을 갖고 있음
이때 ts.config에서 strictFunctionTypes 체크 되어 있어아함
체크 안되어 있으면 타입스크립트는 매개변수에 대해 이변성을 띔
반환값에서의 공변성 사례
1.
a -> b 인 상황
number | string => number
function a (x:string):number {return Number(x)}
type B = (x:string) => number | string;
let b:B = a;
a의 반환값을 b에 대입할 수 있음
함수의 반환값은 공변성을 가지고 있음
2.
b -> a 인 상황
number -> number | string
type B = (x:string) => number;
let b:B = (x:string):number | string => {return Number(x)}
이건 불가능함
string | number를 number에 대입할 수 없다는 에러가 나옴
그러나 매개변수는 반공변성을 가짐
매개변수에서의 반공변성 사례
type B = (x:string) => number;
const a :B= (x:number|string) => {return Number(x)}
string -> string | number
매개변수는 이게 가능함
b -> a
type B = (x:string|number) => number;
const a :B= (x:number) => {return Number(x)}
string | number => number
매개변수는 반공변성이기 때문에 이건 에러 나옴
그러나 여기서 ts의 strict 옵션을 해제하면 에러 안 나옴
매개변수는 strict 옵션일 때 반공변성
strict 옵션이 아닐 때는 이변성을 가지기 때문
(이변성은 a -> b 가능 b -> a 도 가능)
헷갈리는 거.... 지금도 헷갈림...
interface SayMethod {
say(a:string | number):string;
}
interface SayMethodObj {
say : (a:string | number) => string;
}
const sayFunc = (a:string) => "hi";
/** 이때는 이변성을 가짐, 에러 안 남 */
const test :SayMethod = { say: sayFunc }
/** 이때는 반공변성을 가짐, 에러남 */
const test2 : SayMethodObj = { say: sayFunc }
기본적으로 sayFunc 은 (a:string) => string 이라서
반공변성에 의해서
(a:string | number) => string
여기에 대입 못함
근데 SayMethod는 에러 안 남
함수: (매개변수) : 반환값
형식의 타입은 이변성을 가지기 때문임
함수 : (매개변수) => 반환값
형식은 반공변성을 가지기 때문에 test2는 에러남
화살표 함수(함수 표현식) 쓰면 매개변수는 반공변성
선언형 함수는 이변성을 가짐
느낀점
a -> b
b -> a
저 표현이 이해하기 힘들다...
그냥 코드로 보면 대강 알 수 있는데....
그리고 여러모로 화살표 함수 쓰는 게 좋긴 한 거 같다
'TIL' 카테고리의 다른 글
타입스크립트 - enum (0) | 2024.08.18 |
---|---|
타입스크립트 - class (0) | 2024.08.18 |
타입스크립트 오버로딩 (0) | 2024.08.11 |
싱글톤 (0) | 2024.08.04 |
클로저 - hof - 리액트 - hoc - class (0) | 2024.08.04 |
댓글