logo
Search검색어를 포함하는 게시물들이 최신순으로 표시됩니다.
    Table of Contents
    [TS] 타입 추론, 타입 단언, 타입 가드

    이미지 보기

    [TS] 타입 추론, 타입 단언, 타입 가드

    • 22.06.17 작성

    • 읽는 데 6

    TOC

    타입 추론(Type Inference)

    타입 추론이란?

    // parameter의 type으로 return 값의 type이 결정
    function getB(b) {
      return b;
    }
    
    // parameter의 type으로 return 값의 type이 결정
    function getB(b) {
      const c = 'hi'
      return b + c;
    }
    
    • number + string = string으로 type 추론
    • return 값이 내부적으로 string으로 추론

    인터페이스와 제네릭에서의 타입 추론

    인터페이스와 제네릭

    interface Dropdown<T> {
      value: T;
      title: string;
    }
    
    const shoppingItem: Dropdown<string> = {
      value: 'abc',
      title: 'hello',
    }
    

    인터페이스의 상속

    interface Dropdown<T> {
      value: T;
      title: string;
    }
    
    // 관행적으로 T를 쓰지만 구분을 위해 K 사용
    interface DetailedDropdown<K> extends Dropdown<K> {
      description: string
      tag: K;
    }
    
    const detailedItem: DetailedDropdown<string> = {
      value: 'abc',
      title: 'hello',
      description: '안녕하세요~~',
      tag: 'a'
    }
    

    인터페이스 A를 상속받은 인터페이스 B는 generic의 Type도 상속 가능


    Best Common Type

    배열 내에 type이 여러 종류가 있는 경우

    const arr: (number | string | boolean)[] = [1, 2, 3, 'a', 'b', 'c', true];
    

    유니온 타입을 이용해 배열에 들어간 개체들의 타입을 추론해 union type으로 정의

    image

    Typescript Language Server

    • Typescript 작성 중에 오류를 확인하기 위해 실시간으로 동작
    • VS Code의 IntelliSence가 동작하기 위해서도 사용

    타입 단언(Type Assertion)

    타입 단언의 필요성

    let a;
    a = 20;
    a = 'a';
    let b = a;
    
    • any였던 a가 중간의 코드를 거치며 type이 확정
    • 하지만 이후의 a를 참조하는 b는 a의 중간 코드를 모르므로, 처음에 선언했던 any type으로 지정

    let a;
    a = 20;
    a = 'a';
    let b = a as string;
    
    image
    • "TS보다 개발자가 더 코드를 잘 알고 있다! 그러니 내가 지정한대로 해라!"
    • DOM API를 사용할 때 많이 사용

    DOM API와 타입 단언

    <div id="app">hi</div>
    const app = document.querySelector('#app');
    
    • app의 type은 HTMLDivElement
    • 하지만 실무에서는 이렇게 깔끔하게 펼쳐지지 않는다.
    image
    • HTMLDivElement일 수도 있지만 null 일 수도 있다는 의미!

    HTMLDivElement임을 증명하자

    const div = document.querySelector('div') as HTMLDivElement;
    if (div) {
      div.innerText;
    }
    
    • HTMLDivElement가 확실하다고 개발자가 전달
    • HTMLDivElement에서 지원하는 DOM API 사용 가능

    타입 가드

    타입 가드의 필요성

    interface Developer {
      name: string;
      skill: string;
    }
    
    interface Person {
      name: string;
      age: number;
    }
    
    function introduce(): Developer | Person {
      return { name: 'Tony', age: 33, skill: 'Iron Making' }
    }
    
    • 위의 두 interface로 정의된 introduce 함수의 반환값은 두 interface의 union type
    image
    • tony는 name만 접근할 수 있다. 두 interface에 공통으로 존재하기 때문!
    • 반대로 생각하면 tony가 Developer interface인데 Person interface의 속성을 쓰면 안되기 때문

    const tony = introduce();
    if ((tony as Developer).skill) {
      const skill = (tony as Developer).skill;
      console.log(skill);
    } else if ((tony as Person).age) {
      const age = (tony as person).age;
      console.log(age);
    }
    
    • tony의 두 interface type에 대하여 타입 단언으로 있으나 없으나 사용
    • 없으면 if문에서 걸러지고, 있으면 if문 내부에서 사용 가능

    좀 더러운데요?

    • 타입단언 코드도 반복되고 좀 더럽긴 하다.

    타입 가드의 활용

    function isDeveloper(target: Developer | Person): target is Developer {
      return (target as Developer).skill !== undefined;
    }
    
    • Developer일지, Person일지 모르는 target을 전달받음
    • 이를 Developer로 간주하고 skill을 찍었을 때, Developer면 string, Person이면 undefined
    • 만약 true이면 target을 Developer로 한다.

    위의 함수를 사용해보자.

    // if ((tony as Developer).skill) {
    //   const skill = (tony as Developer).skill;
    //   console.log(skill);
    // } else if ((tony as Person).age) {
    //   const age = (tony as person).age;
    //   console.log(age);
    // }
    
    if(isDeveloper(tony)) {
      console.log(tony.skill)
    } else {
      console.log(tony.age)
    }
    
    profile

    FE Developer 박승훈

    노력하는 자는 즐기는 자를 이길 수 없다