타입스크립트

아이템 19 - 추론 가능한 타입을 사용해 장황한 코드 방지하기

rosaleee 2023. 3. 14. 08:18

타입 추론이란?

타입스크립트에서 타입 구문을 명시하지 않는다면, 일반적으로 변수의 타입 혹은 함수가 반환하는 타입은 처음 등장할 때 결정되는데, 이것을 타입 추론이라고 합니다.

  • 변수의 타입을 명시하지 않고 값을 할당할 경우

    let x = 12; // number 타입으로 추론
    
    const person = {
      name: 'Sojourner Truth',
      born: {
        where: 'Swartekill, NY',
        when: 'c.1797',
      }
    }; // { name: string; born: { where: string; when: string; }; } 타입으로 추론
  • 함수의 반환 타입을 명시하지 않았을 경우

    function square(nums: number[]) {
      return nums.map(x => x * x);
    }
    const squares = square([1, 2, 3, 4]); // number[] 타입으로 추론

이처럼 타입 추론은 타입 구문을 생략하여 장황한 코드를 작성하지 않게 함으로써 코드를 읽는 사람이 구현 로직에 집중할 수 있게 해줍니다.

그러면 언제 타입 추론을 활용하는 것이 좋고, 언제 타입을 명시하는 것이 좋은지 알아봅시다.

타입 추론을 활용하는 경우

  • 원시값을 할당

    let str = 'string';
    const bool = true;
    const num = 12;
  • 함수 내에서 생성된 지역 변수

    interface Product {
      id: string;
      name: string;
      price: number;
    }
    function logProduct(product: Product) {
      const { id, name, price } = product; // 비구조화 할당문을 사용
        /* ... */
    }
  • 함수에서 기본값이 있는 매개변수

    function parseNumber(str: string, base = 10) {
        /* ... */
    }
  • 타입 정보가 있는 라이브러리에서 콜백 함수의 매개변수

    namespace express {
      export interface Request {}
      export interface Response {
        send(text: string): void;
      }
    }
    interface App {
      get(path: string, cb: (request: express.Request, response: express.Response) => void): void;
    }
    const app: App = null!;
    
    // Don't do this:
    app.get('/health', (request: express.Request, response: express.Response) => {
      response.send('OK');
    });
    
    // Do this:
    app.get('/health', (request, response) => {
      response.send('OK');
    });

타입을 명시하는 경우

  • 객체 리터럴 정의

    객체 리터럴을 정의할 때, 타입을 명시하면 타입스크립트는 잉여 속성 체크를 하기 때문에 객체가 사용되는 곳에서 오류가 발생하는 것이 아니라 객체를 선언한 곳에 오류가 발생합니다.

    interface Product {
      id: string;
      name: string;
      price: number;
    }
    
    // 타입을 명시하지 않은 경우
    const furby = {
        id: 630509430963,
        name: 'Furby',
        price: 35,
    };
    logProduct(furby);
            // ~~~~~ Argument .. is not assignable to parameter of type 'Product'
            //         Types of property 'id' are incompatible
            //         Type 'number' is not assignable to type 'string'
    
    

// 타입을 명시한 경우
const typedFurby: Product = {
id: 630509430963, // ~~ Type 'number' is not assignable to type 'string'
name: 'Furby',
price: 35,
};
logProduct(typedFurby);


* 함수의 반환 타입

  함수의 반환 타입을 명시하면 **함수에 대해 더욱 명확하게 알 수 있고, 명명된 타입을 사용할 수 있기 때문**에 타입을 명시하는 것이 좋습니다.

  ```typescript
  interface Vector2D {
    x: number;
    y: number;
  }
  function add(a: Vector2D, b: Vector2D): Vector2D {
    return { x: a.x + b.x, y: a.y + b.y };
  }