템플릿 리터럴 타입

템플릿 문자에도 리터럴 타입처럼 적용할 수 있다.

typeColor="red"|"black"|"green";
typeAnimal="dog"|"cat"|"chicken";

typeColoredAnimal=`red-dog`|'red-cat'|'red-chicken'|'black-dog'...;
typeColoredAnimal=`${Color}-${Animal}`;

조건부 타입

extends와 삼항 연산자를 이용해 조건에 따라 각각 다른 타입을 정의하는 문법

type A = number extends string ? number : string;

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>;
// string

let varB: StringNumberSwitch<string>;
// number

함수 사용시

인자의 타입을 제네릭으로 받는다면, 해당 제네릭을 조건부 타입을 붙여서 사용할 수 있다.

function removeSpaces(text: string | undefined | null) {
  if (typeof text === "string") {
    return text.replaceAll(" ", "");
  } else {
    return undefined;
  }
} 

let result = removeSpaces("hi im winterlood");
// string | undefined

위처럼 여러 타입을 받을 수 있는 경우에 제네릭 조건부로 아래처럼 표현이 가능하다.

function removeSpaces<T>(text: T): T extends string ? string : undefined;
function removeSpaces(text: any) {
  if (typeof text === "string") {
    return text.replaceAll(" ", "");
  } else {
    return undefined;
  }
}

let result = removeSpaces("hi im winterlood");
// string

let result2 = removeSpaces(undefined);
// undefined