본문 바로가기
프로그래밍/TypeScript

조건부 타입

by hi-rachel 2023. 10. 24.

조건부 타입

조건부 타입 소개

/**
 * 조건부 타입
 */

// 앞에 있는 타입이 뒤에 있는 타입의 서브 타입인지 확인해서 맞다면 ? 뒤, 틀리다면 : 뒤 타입 할당
type A = number extends string ? string : number;

type ObjA = {
  a: number;
};

type ObjB = {
  a: number;
  b: number;
};

type B = ObjB extends ObjA ? number : string;

/**
 * 제네릭과 조건부 타입
 */

type StringNumberSwitch<T> = T extends number ? string : number;

let varA: StringNumberSwitch<number>;

let varB: StringNumberSwitch<string>;

// 오버로드 시그니쳐
function removeSpaces<T>(text: T): T extends string ? string : undefined;
function removeSpaces(text: any) {
  if (typeof text === "string") {
    return text.replaceAll(" ", "");
  } else {
    return undefined as any;
  }
}

let result = removeSpaces("hi i'm rachel pink");
result.toLowerCase();

분산적인 조건부 타입

/**
 * 분산적인 조건부 타입
 */

// 분산적으로 작동하고 싶지 않다면 extends 양 옆에 []
// type StringNumberSwitch<T> = [T] extends [number] ? string : number;
// c, d -> number

type StringNumberSwitch<T> = T extends number ? string : number;

let a: StringNumberSwitch<number>;

let b: StringNumberSwitch<string>;

let c: StringNumberSwitch<number | string>;

let d: StringNumberSwitch<boolean | number | string>;
// 1단계
// StringNumberSwitch<boolean>
// StringNumberSwitch<number>
// StringNumberSwitch<string>

// 분리된 후 유니온으로 묶인다
// 2단계
// number |
// string |
// number

// 결과
// number | string

/**
 * 실용적인 예제
 */

// T와 U가 같을 때 never를 반환하게 해서 아예 타입을 없애고,
// T와 U가 같을 때 T 타입 반환
type Exclude<T, U> = T extends U ? never : T;

type A = Exclude<number | string | boolean, string>;
// 1단계
// Exclude<number, string> |
// Exclude<string, string> |
// Exclude<boolean, string>

// 2단계
// number |
// never |
// boolean

// 결과
// number | never | boolean
// -> number | boolean

// 반대 예시
type Extract<T, U> = T extends U ? T : never;

type B = Extract<number | string | boolean, string>;
// 1단계
// Extract<number, string>
// Extract<string, string>
// Extract<boolean, string>

// 2단계
// never |
// string |
// never

// 결과
// string

infer - 조건부 타입 내에서 타입 추론하기

/**
 * infer - 조건부 타입 내에서 타입 추론하기
 */

type FuncA = () => string;

type FuncB = () => number;

type ReturnType<T> = T extends () => infer R ? R : never;

type A = ReturnType<FuncA>; // string

type B = ReturnType<FuncB>; // number

type C = ReturnType<number>; // R을 추론할 수 없어 거짓 -> never

/**
 * 예제
 */

type PromiseUnpack<T> = T extends Promise<infer R> ? R : never;
// 1. T는 프로미스 타입이어야 한다.
// 2. 프로미스 타입의 결괏값 타입을 반환해야 한다.

type PromiseA = PromiseUnpack<Promise<number>>; // number

type PromiseB = PromiseUnpack<Promise<string>>; // string

[참고]

한 입 크기로 잘라먹는 타입스크립트

  • Section 9. 조건부 타입 강의를 듣고 정리한 내용입니다.

'프로그래밍 > TypeScript' 카테고리의 다른 글

유틸리티 타입  (1) 2023.10.26
타입 조작하기  (0) 2023.10.24
타입스크립트 제네릭  (0) 2023.10.23
타입스크립트 클래스  (1) 2023.10.23
타입스크립트 인터페이스  (0) 2023.10.23