[한입] 조건부 타입

TK·2023년 12월 21일
0

[강의] 한입 시리즈

목록 보기
53/59

조건부 타입

삼항연산자를 이용해서 조건에 따라 타입을 결정한다.

type A = number extends string ? string : number; // number타입

✏️객체타입

type ObjA = {
  a: number;
};

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

type B = ObjB extends ObjA ? string : number; // number타입

✏️제네릭타입

참고: 제네릭타입 형태

type StringNumberSwitch<T> = T extends number ? string : number;
let varA: StringNumberSwitch<number>; // string
let varB: StringNumberSwitch<string>; // number

예제

  • 다음과 같은 코드가 있다.
function removeSpaces(text: string) {
  return text.replaceAll(" ", "");
}

let result = removeSpaces("hi im winterlood"); //"hiimwinterlood"
result.toUpperCase();

  • 여기서 매개변수 text의 타입에 undefinednull값을 추가하면 다음과 같은 오류가 발생한다.
function removeSpaces(text: string | undefined | null) {
  return text.replaceAll(" ", ""); //❌오류 →string메서드 사용불가
}

let result = removeSpaces("hi im winterlood"); //"hiimwinterlood"
result.toUpperCase();

  • 조건문을 이용해서 타입 좁히기한다.
    → 함수 내부 오류는 사라지지만 result변수 타입이 string|undefined로, 문자열 메서드 사용이 불가해 오류 발생
function removeSpaces(text: string | undefined | null) {
  if (typeof text === "string") {
    return text.replaceAll(" ", "");
  } else {
    return undefined;
  }
}

let result = removeSpaces("hi im winterlood");
result.toUpperCase(); //❌오류 →string메서드 사용불가

  • 조건부 타입을 사용하여 다음과 같이 해결한다.
function removeSpaces<T>(text: T): T extends string ? string : undefined {
  if (typeof text === "string") {
    return text.replaceAll(" ", ""); //❌오류
  } else {
    return undefined; //❌오류
  }
}

let result = removeSpaces("hi im winterlood"); //✅
result.toUpperCase(); //✅
let result2 = removeSpaces(undefined); //✅

  • 함수내부에 발생한 오류는 다음과 같이 변경한다.(함수내부에서는 조건부타입의 결과가 어떻게 될지 알수 없기 때문에 발생한 오류)
  1. any타입으로 단언 → 숫자를 전달해도 검사불가
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 {
  if (typeof text === "string") {
    return text.replaceAll(" ", "") as any; //👈
  } else {
    return undefined as any; //👈
  }
}

let result = removeSpaces("hi im winterlood");
result.toUpperCase();
let result2 = removeSpaces(undefined);

  1. 함수 오버로딩 → 오버로드 시그니처 만듦
function removeSpaces<T>(text: T): T extends string ? string : undefined; //👈
function removeSpaces<T>(text: any) {
  if (typeof text === "string") {
    return text.replaceAll(" ", "");
  } else {
    return undefined;
  }
}

let result = removeSpaces("hi im winterlood");
result.toUpperCase();
let result2 = removeSpaces(undefined);
    • string타입이 아닌 타입을 반환할 때 문제 감지
    • undefined이 아닌 값을 반환할 때 문제 감지
profile
쉬운게 좋은 FE개발자😺

0개의 댓글