# 조건부 타입(Conditional Type)이란?

조건부 타입은 조건에 따라 다른 타입을 선택할 수 있는 문법입니다. 마치 자바스크립트의 삼항 연산자처럼 조건을 확인한 후 조건에 따라 다른 타입을 추론해 줍니다.

TIP

자바스크립트의 삼항 연산자란 조건식이 맞으면 첫 번째 값을 반환하고 틀리면 두 번째 값을 반환하는 문법입니다.

조건 ? 첫 번째 값 : 두 번째 값

# 조건부 타입 기본 문법

조건부 타입의 기본 문법은 다음과 같습니다.

조건식 ? 첫번째타입 : 두번째타입

조건식이 참이면 첫번째타입이 되고, 거짓이면 두번째타입이 됩니다. 조건식은 대부분 TypeA extends TypeB와 같이 extends로 구성됩니다.

간단한 예제 코드를 봅시다.










 

interface Person {
  name: string;
  age: number;
}

interface Developer extends Person {
  skill: string;
}

type Result = Developer extends Person ? string : number; // string

위 코드에서 Result 타입은 string이 됩니다. 왜냐하면 앞의 조건식 Developer extends Person이 참이기 때문이죠. 만약 아래 코드라면 어떤 타입이 되었을까요?

type Result = Developer extends boolean[] ? string : number; // number

Result의 타입은 number가 됩니다. boolean[]의 하위 타입이 Developer가 될 수 없기 때문이죠.

# 조건부 타입이 유용한 경우

조건부 타입은 주로 제네릭을 사용할 때 유용합니다. 제네릭으로 받은 타입이 예상되는 범위 안에 있는지 확인할 때 사용하면 좋죠. 아래 코드를 보겠습니다.

interface Person {
  name: string;
  age: number;
}

interface Developer {
  name: string;
  skill: string;
}

type SkillProperty<T> = T extends { skill: string } ? T['skill'] : never;

위 코드에서 SkillProperty<T> 타입은 제네릭으로 넘겨 받은 T 타입에 skill 이라는 속성이 있는지 확인하고, 있다면 해당 속성에 지정된 타입을 반환해 줍니다.

이 타입에 Person, Developer 인터페이스를 대입하면 각각 neverstring이 나옵니다.

type A = SkillProperty<Person>; // never
type B = SkillProperty<Developer>; // string

위 코드에서 A 타입은 Person 인터페이스에 skill 속성이 없으므로 never가 됩니다. B 타입은 Developer 인터페이스에 skill 속성이 있고 string 타입이므로 string이 됩니다.

# 조건부 타입의 다른 예시들

이외에도 조건부 타입은 다음과 같이 활용할 수 있습니다.

type IsString<T> = T extends string ? string : never;
type A = IsString<string>; // string
type B = IsString<boolean>; // never
type Filter<Type, ManyTypes> = Type extends ManyTypes ? Type : never;
type A = Filter<string, string | number>; // string
type B = Filter<boolean, string | number | boolean>; // boolean