3장 타입추론
🛷

3장 타입추론

생성일
Oct 15, 2021 11:18 PM
태그
ts
타입 추론은 수동으로 명시해야 하는 타입 구문의 수를 엄청나게 줄여 주기 때문에, 코드의 전체적인 안정성이 향상된다. 숙련되면 비교적 적은 수의 타입 구문을 사용할 수 있다.
 

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

  • 타입 추론이 된다면 명시적 타입 구문은 필요하지 않다.
    • 불필요한 타입 구문을 작성하는 것은 거추장스러울 뿐이다.
  • 정보가 부족해서 타입스크립트가 스스로 타입을 판단하기 어려운 상황에서 명시적 타입 구문이 필요.
  • 이상적인 타입스크립트 코드는 함수/메서드 시그니처에 타입 구문을 포함하지만, 함수 내에서 생성된 지역 변수에는 타입 구문을 넣지 않는다.
    • 타입 구문을 생략하여 방해되는 것들을 최소화하자.
  • 보통 타입 정보가 있는 라이브러리에서, 콜백 함수의 매개변수 타입은 자동으로 추론해줌.
    • // express.Request 타입 생략해도됨..
      api.get("/main", (req: express.Request, res: express.Response) => { 
        res.send("ok");
      });
      
      // req, res에 express.Request, Response 타입이 추론되어있음
      api.get("/main", (req, res) => {
        res.send("ok");
      });
 
  • 객체 리터럴을 정의할 때 타입을 명시하면 잉여 속성 체크가 동작해서 유용하다.
  • 함수의 반환에도 타입을 명시하여 오류를 방지할 수 있다.
    • 타입 추론이 가능하더라도 구현상의 오류가 함수를 호출한 곳까지 영향을 미치지 않도록 하기 위해 타입구문을 명시하는게 좋다.
 
  • 명명된 타입을 반환하면 좋은 경우
interface Vector2D {
  x: number;
  y: number;
}

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

// 위 코드에서 반환값은 { x : number, y: number } 로 추론된다.
// 사용자 입장에서 Vector2D 타입으로 추론되는게 이해하기 쉬워서 타입을 명시하면 좋음.
 
 

아이템 20 다른 타입에는 다른 변수 사용하기

let id = '12-34'; // type : string

id = 123123 // type : number
  • 자바스크립트에서는 동작하는 코드이지만, 타입스크립트에서는 타입 에러 발생함. (타입스크립트는 초기화 될 때 타입추론으로 타입을 지정한다)
 
  • 위 문제는 유니온 타입으로 타입을 확장해서 에러를 피할 수 있다.
    • 하지만 id를 사용할 때마다 값이 어떤 타입인지 확인해야 하기 때문에 다루기 더 어렵다.
    • 차라리 string, number 각각 별도의 변수를 도입하는 것이 낫다.
 
  • 별도의 변수를 사용하는 게 바람직한 이유
    • 서로 관련없는 두개의 값을 분리
    • 변수명을 더 구체적으로 지을 수 있음
    • 타입 추론을 향상시키며, 타입 구문이 불필요해진다
    • 타입이 더 간결해진다
    • let 대신 const 변수를 선언하게 된다.
 
  • 변수의 값은 바뀔 수 있지만, 그 타입은 보통 바뀌지 않는다.
  • 혼돈을 막기 위해 타입이 다른 값을 다룰 때에는 변수를 재사용하지 말자.
 
 

아이템 21 타입 넓히기

  • 타입스크립트가 작성된 코드를 체크하는 정적 분석 시점에, 변수는 가능한 값들의 집합인 타입을 가진다.
  • 상수를 사용해서 변수를 초기화 할 때 타입을 명시하지 않으면 타입체커는 지정된 단일 값을 가지고 할당 가능한 값들의 집합을 유추해야한다. 이러한 과정을 '넓히기'라고 부른다.
  • 넓히기 과정을 이해한다면 오류의 원인을 파악하고 타입 구문을 더 효과적으로 사용할 수 있다.
 
interface Vector3 {
  x: number;
  y: number;
  z: number;
}

function getComponent(vector: Vector3, axis: "x" | "y" | "z") {
  return vector[axis];
}

let x = "x";
let vec: Vector3 = { x: 10, y: 10, z: 10 };

// ERR : 'string' 형식의 인수는 '"x" | "y" | "z"' 형식의 매개 변수에 할당될 수 없습니다.
getComponent(vec, x);
  • 위의 코드에서 x는 string으로 추론되기 때문에 에러가 발생한다.
  • 타입스크립트는 타입을 추론할 때 명확성과 유연성 사이의 균형을 유지하려고 한다.
    • 추측한 답이 항상 옳을 수는 없다.
 
  • let 대신 const로 변수를 선언하면 더 좁은 타입이 된다.
    • const y = "y"; // type : 'y'
    • 하지만 const는 만능이아니다. 객체나 배열의 경우에 여전히 문제가 있다.
 
  • 타입추론의 강도를 직접 제어하려면 타입스크립트의 기본동작을 재정의해야 한다.
    • 명시적 타입 구문 제공
    • 타입 체커에 추가적인 문맥 제공
    • as const 단언문 사용
      • let const와 다르다. 온전히 타입 공간의 기법
      • 값 뒤에 as const를 작성하면, 타입스크립트는 최대한 좁은 타입으로 추론한다.

Loading Comments...