number extends string은 number 타입이 string 타입의 서브타입이 아니다.
따라서 타입 A는 string 타입이기 때문에 조건문은 거짓이 된다.
ObjB는 ObjA의 서브타입이다.
따라서 타입 B는 number 타입이므로 조건문은 참이 된다.
제네릭 조건부 타입
타입 변수에 Number 타입이 할당되면 String 타입을 반환하고 그렇지 않다면 Number 타입을 반환한다.
매개변수로 string 타입의 값을 제공받아 공백을 제거한 다음 반환하는 함수
매개변수에 undefined나 null 타입의 값들도 제공될 수 있다고 가정
type StringNumberSwitch<T> = T extends number ? string : number;
let varA : StringNumberSwitch<number>;
// string
let varB : StringNumberSwitch<string>;
// string
varA: T에 number 할당 -> 조건식 참 -> string 타입이 된다.
varB: T에 string 할당 -> 조건식 거짓 -> number 타입이 된다.
분산적인 조건부 타입
조건부 타입의 타입 변수에 Union 타입을 할당하면 분산적인 조건부 타입으로 조건부 타입이 업그레이드된다.
✅ 분산적인 조건부 타입 동작 과정
타입 변수에 할당한 Union 타입 내부의 모든 타입이 분리
그 결과 각 타입의 결과를 다시 Union 타입으로 묶기
infer
조건부 타입 내에서 특정 타입을 추론
특정 함수 타입에서 반환값의 타입만 추출하는 특수한 조건부 타입인 ReturnType을 만들 때 이용할 수 있다.
추론이 불가능하다면 조건식을 거짓으로 판단한다.
type ReturnType<T> = T extends () => infer R ? R : never;
type FuncA = () => string;
type FuncB = () => number;
type A = ReturnType<FuncA>;
// string
type B = ReturnType<FuncB>;
// number
✅ A 타입을 계산할 때의 코드의 흐름
타입 변수 T에 함수 타입 FuncA가 할당된다.
T는 () ⇒ string
조건부 타입의 조건식 형태: () ⇒ string extends () ⇒ infer R ? R : never
조건식을 참으로 만드는 R 타입을 추론. 그 결과 R은 string으로 추론된다.
추론이 가능하면 이 조건식을 참으로 판단. 따라서 결과는 string이 된다.
유틸리티 타입
타입스크립트가 제공하는 특수한 타입들
제네릭, 맵드 타입, 조건부 타입 등의 타입 조작 기능을 이용해 실무에서 자주 사용되는 유용한 타입들을 모아 놓은 것
유틸리티 타입을 쓰면 훨씬 더 간결한 문법으로 타입을 정의할 수 있으며 특히 이미 정의해 놓은 타입을 변환할 때 유용하게 쓰인다.
✅ Partial<T>
부분적인 또는 일부분의라는 뜻
특정 객체 타입의 모든 프로퍼티를 선택적 프로퍼티로 변환한다.
타입 변수 T로 전달한 객체 타입의 모든 프로퍼티를 전부 선택적 프로퍼티로 변환한다.
기존 객체 타입에 정의된 프로퍼티들 중 일부분만 사용할 수 있도록 도와주는 타입이다.
✅ Required<T>
필수의, 필수적인이라는 뜻
특정 객체 타입의 모든 프로퍼티를 필수(required) 프로퍼티로 변환한다.
Required는 Post 타입의 모든 프로퍼티가 필수 프로퍼티로 변환된 객체 타입이다.
thumbnailURL 프로퍼티를 생략하면 오류가 발생한다.
-? 는 ?가 붙어있는 선택적 프로퍼티가 있으면 ?를 제거하라는 의미이다.
✅ Readonly
읽기 전용이라는 뜻
특정 객체 타입의 모든 프로퍼티를 읽기 전용 프로퍼티로 변환한다.
Readonly는 Post 타입의 모든 프로퍼티를 readonly(읽기 전용) 프로퍼티로 변환한다.
점표기법을 이용해 특정 프로퍼티의 값을 수정하려고 하면 오류가 발생한다.
✅ Pick<T, K>
뽑다, 고르다라는 뜻
특정 객체 타입으로부터 특정 프로퍼티만을 골라내는 타입
T로부터 K 프로퍼티만 뽑아낸 객체 타입을 만들어야 하므로 맵드 타입으로 정의한다.
K가 T의 Key로만 이루어진 String Literal Union 타입임을 보장해주어야 하므로 제약을 추가한다.