ABOUT ME

Today
Yesterday
Total
  • 아이템 22 - 타입 좁히기
    타입스크립트 2023. 3. 14. 18:05

    여러가지 타입이 가능할 때, 문맥에 따라 특정 타입으로 추론하게 하는 방법

    타입 좁히기는 타입스크립트가 넓은 타입으로부터 좁은 타입으로 추론하는 과정을 말하는데, 다음과 같은 방법으로 타입을 좁힐 수 있습니다.

    • 조건문

      const el = document.getElementById('foo'); // Type is HTMLElement | null
      if (el) {
        el // Type is HTMLElement
      } else {
        el // Type is null
      }
    • 예외를 던지거나 함수를 반환(early return)

      // 예외를 던지는 방법
      const el = document.getElementById('foo'); // Type is HTMLElement | null
      if (!el) throw new Error('Unable to find #foo');
      el; // Now type is HTMLElement
    • instanceof

      function contains(text: string, search: string|RegExp) {
        if (search instanceof RegExp) {
          search  // Type is RegExp
          return !!search.exec(text);
        }
        search  // Type is string
        return text.includes(search);
      }
    • 속성 체크

      interface A { a: number }
      interface B { b: number }
      function pickAB(ab: A | B) {
        if ('a' in ab) {
          ab // Type is A
        } else {
          ab // Type is B
        }
        ab // Type is A | B
      }
    • Array.isArray

      function contains(text: string, terms: string|string[]) {
        const termList = Array.isArray(terms) ? terms : [terms];
        termList // Type is string[]
        // ...
      }
    • 태그된 유니온(tagged union) 또는 구별된 유니온(discriminated union)

      각 객체의 동일한 프로퍼티에 객체마다 다른 값을 지정하여 서로 다른 객체를 구분하는 방법

      interface UploadEvent { type: 'upload'; filename: string; contents: string }
      interface DownloadEvent { type: 'download'; filename: string; }
      type AppEvent = UploadEvent | DownloadEvent;
      
      function handleEvent(e: AppEvent) {
        switch (e.type) {
          case 'download':
            e  // Type is DownloadEvent
            break;
          case 'upload':
            e;  // Type is UploadEvent
            break;
        }
      }
    • 타입 식별을 돕기 위한 커스텀 함수

      function isInputElement(el: HTMLElement): el is HTMLInputElement {
        return 'value' in el;
      }
      
      function getElementContent(el: HTMLElement) {
        if (isInputElement(el)) {
          el; // Type is HTMLInputElement
          return el.value;
        }
        el; // Type is HTMLElement
        return el.textContent;
      }

      함수의 반환 타입에 el is HTMLInputElement 라고 지정하면, 함수의 반환되는 값이 true 인 경우 타입 체커에게 매개변수의 타입을 좁힐 수 있다고 알려줄 수 있습니다. 이러한 기법을 사용자 정의 타입 가드라고 합니다.

    댓글

Designed by Tistory.