타입을 다이나믹하게 지정하는 방법을 알아보자
조건식 ? 참일 때 실행 : 거짓일 때 실행
삼항연산자는 위와 같은 형식을 가지고 있는 if문 대신 사용가능한 조건문이다.
이런 코드가 있다고 가정하자
let a :number;
a > 3 ? console.log("a는 3보다 크다") : console.log("a는 3보다 작다")
만약 a에 5가 들어가면 조건식이 참이 되기 때문에 "a는 3보다 크다" 가 출력될 것이다
하지만 a에 1이 들어가게 된다면 조건식이 거짓이 되기 때문에 "a는 3보다 작다" 가 출력될것이다
type ABC<T> = T;
let a :ABC<number>;
먼저 ABC라는 타입을 하나 만들었다
<>
타입 파라미터 안에는 number 타입을 넣었기 때문에 그대로 남겨준다.
코드를 다이나믹하게 바꿔보자
<>
타입 파라미터 자리 안에 들어오는 타입의 종류에 따라 타입을 다르게 지정할 수 있다.
type ABC<T> = T extends number ? number : unknown;
let a :ABC<number>;
여기서 조건식에서 타입을 확인하기 위해서는 무조건 extends를 사용해야 한다
위 코드에서는 타입파라미터 안에 number를 사용했기 때문에 조건식이 참이 되어 number 자료형이 남는다
let a :ABC<boolean>;
만약 이렇게 number가 아닌 자료형을 사용하면 조건식이 거짓이 되어 unknown 자료형을 남기게 되는 것이다.
infer
조건문에서 쓸 수 있는 infer 키워드이다
타입을 왼쪽에서 추출해주는 역할을 한다
바로 예시로 보자
type XYZ<T> = T extends infer R ? R : unknown;
type 새타입 = XYZ<string> // 타입은 string 타입입니다
이 코드에서는 왼쪽에는 T 타입이 있다.
infer 키워드를 사용하면 왼쪽에 있는 T 타입을 추출해와서 R에 할당된다
T는 XTZ<string>
에서 string으로 정해져 있기 때문에 R 또한 string이 되는 것이다.
다음으로 array 자료형이다
type OldType<T> = T extends (infer R)[] ? R : unknown;
type NewType = OldType boolean[];
array 자료형은 infer랑 같은 위치에 있는 자료형을 추출해온다
지금 OldType에는 boolean[] 이 지정되어 있는데 (infer R)[] 에서 infer R 의 위치가 boolean 위치랑 같으므로 R은 boolean 이 되는 것이다
조금 이해가 어려울 수도 있다...
함수의 return 타입
type OldType<T> = T extends ( () => infer R ) ? R : unknown;
type NewType = OldType () => void;
위에서 같은 위치에 있는 type을 뽑아서 R에다가 준다고 했는다
지금 T의 타입은 () => void
타입이 되고
infer R의 위치가 void랑 같은 위치에 있으므로 R은 void
가 되는 것이다
사실 지금까지 이런 infer 키워드는 거의 사용되지 않고 만약 함수의 리턴타입을 추출해서 사용하고 싶다 하면
ReturnType<() => void>