내일배움캠프 TIL (230123)

Jiumn·2023년 1월 23일
0

타입스크립트 타입 좁히기 (type narrowing) 종류


typeof 연산자로 타입 좁히기

어떤 함수의 매개변수가 유니온 타입일 때, 합수의 결과 값을 미리 지정할 수가 없다. 매개변수의 타입에 따라 결과값도 달라지기 때문이다.

그러므로 if문으로 타입을 좁히는타입 좁히기(type narrowing)가 필요하다.

먼저 typeof 연산자를 사용해서 매개변수의 타입을 판별하는 방법이 있다.

function triple(value: number | string) {
  if (typeof value === "string") {
    return value.repeat(3);
  }
  return value * 3;
}

위의 코드처럼 매개변수가 string 타입인 경우 ,타입스크립트가 문자로 인식해 문자열에 사용할 수 있는 메서드(repeat)를 사용할 수 있도록 허용해준다.

그렇지 않은 경우(숫자인 경우) 결과값도 숫자로 반환된다.


Truthiness로 타입 좁히기

만약 매개변수의 타입이 어떤 자료형과 null(또는 undefined)라면 Truthiness로 판별할 수 있다.

const printletters = (word?: string) => {
  if (word) {
    for (let char of word) {
      console.log(char);
    }
  } else {
    console.log("문자를 전달하지 않음!");
  }
};

예를 들어 위와 같이 word가 존재하거나 존재하지 않는 경우를 나눠서 타입 좁히기를 하면 된다.


일치 연산자(===, 삼중 등호, strict equal operator)로 타입 좁히기

두 매개변수가 같은 자료형을 가질 수 있는 경우, ===(일치 연산자, 삼중 동호)를 사용해서 타입 좁히기를 할 수 있다.

function someDemo(x: string | number, y: string | boolean) {
  if (x === y) {
    x.toUpperCase();
  }
}
someDemo(3, "3");

x와 y가 같은 자료형, 즉 string인 경우에는 결과값으로도 문자열을 반환한다.
위 코드에서처럼 toUpperCase와 같은 문자열에만 적용할 수 있는 메서드를 사용해도 에러가 발생하지 않는다.

다만 ==(동등 연산자, 이중 등호, equal operator)로 변경 시 다음과 같은 에러가 발생한다. 타입스크립트가 자료형을 구분하지 못하기 떄문이다.

index.js:30 Uncaught TypeError: x.toUpperCase is not a function
    at someDemo (index.js:30:11)
    at index.js:33:1

in 연산자로 타입 좁히기

어떤 함수가 매개변수가 2개 이상의 인터페이스를 유니온 타입으로 가질 때,

interface Movie {
  title: string;
  duration: number;
}

interface TVShow {
  title: string;
  numEpisodes: number;
  episodeDuraiton: number;
}

타입 좁히기를 하려면 in 연산자를 사용한다.
(typeof 연산자를 사용하면 똑같이 객체가 반환되기 때문)

function getRuntime(media: Movie | TVShow) {
  if ("numEpisodes" in media) {
    return media.numEpisodes * media.episodeDuraiton;
  }
  return media.duration;
}

위와 같이 만약 매개변수에 numEpisodes가 있다고 가정하면 해당 매개변수의 인터페이스는 TVShow일 것이고, 그렇지 않으면 Movie라는 걸 타입스크립트가 알 수 있다.

console.log(getRuntime({ title: "Amadeus", duration: 140 }));
console.log(
  getRuntime({ title: "Spongebob", numEpisodes: 90, episodeDuraiton: 30 })
);

콘솔에 찍어보면 첫 번째 줄은 Movie 인터페이스에 근거해서 media.duration를 반환하고,
두 번째 줄은 TVShow 인터페이스에 근거해서 media.numEpisodes * media.episodeDuraiton를 반환한다.


instanceof 타입 좁히기

매개변수가 특정 클래스에 속하는지 확인하는 instanceof 연산자를 사용하는 방법이다.

function printFullDate(date: string | Date) {
  if (date instanceof Date) {
    console.log(date.toUTCString());
  } else {
    console.log(new Date(date).toUTCString());
  }
}
class User {
  constructor(public username: string) {}
}
class Company {
  constructor(public name: string) {}
}
function printName(entity: User | Company) {
  if ("username" in entity) {
    entity;
  } else {
    entity;
  }
}
profile
Back-End Wep Developer. 꾸준함이 능력이다. Node.js, React.js를 주로 다룹니다.

0개의 댓글