[이펙티브 타입스크립트] 아이템51 ~ 아이템54

Yongwoo Cho·2022년 6월 13일
0

TIL

목록 보기
89/98
post-thumbnail

[아이템51] 의존성 분리를 위해 미러 타입 사용하기

미러링 : 필요한 선언부만 추출하여 작성 중인 라이브러리에 넣는 것

만약 작성 중인 라이브러리가 의존하는 라이브러리의 구현과 무관하게 타입에만 의존한다면, 필요한 선언부만 추출하여 작성 중인 라이브러리에 넣는것을 고려해 보는 것도 좋다.

공개한 라이브러리를 사용하는 자바스크립트 사용자가 @types 의존성을 가지지 않게 해야 한다. 그리고 웹 개발자가 NodeJS 관련된 의존성을 가지지 않게 해야 한다.

[아이템52] 테스팅 타입의 함정에 주의하기

  • 타입을 테스트할 때는 특히 함수 타입의 동일성과 할당 가능성의 차이점을 알고 있어야 한다.

  • 콜백이 있는 함수를 테스트할 때, 콜백 매개변수의 추론된 타입을 체크해야 한다. 또한 this가 API의 일부분이라면 역시 테스트해야 한다.

  • 타입 관련된 테스트에서 any를 주의해야 한다. 더 엄격한 테스트를 위해 dtslint같은 도구를 사용하는 것이 좋다.

[아이템53] 타입스크립트 기능보다는 ECMAScript 기능을 사용하기

enum Flavor {
  VANILLA = 0,
  CHOCOLATE = 1,
  STRAWBERRY = 2,
}
let flavor = Flavor.CHOCOLATE; // type : Flavor

👎 타입스크립트에서 열거형(enum)의 문제점

  • 숫자 열거형에 0, 1, 2 외의 다른 숫자가 할당되면 매우 위험
  • 상수 열거형은 보통의 열거형과 달리 런타임에 완전히 제거된다. const enum Flavor로 바꾸면 컴파일러는 Flavor.CHOCOLATE을 0으로 바꾼다.
  • 문자열 열거형 사용시 구조적 타이핑이 아닌 명목적 타이핑을 사용한다.
enum Flavor {
  VANILLA = "VANILLA",
  CHOCOLATE = "CHOCOLATE",
  STRAWBERRY = "STRAWBERRY",
}
let flavor = Flavor.CHOCOLATE; // type : Flavor
flavor = "VANILLA"; // ❌ ~~ '"VANILLA'"형식은 'Flavor' 형식에 할당될 수 없습니다

❗ 자바스크립트와 타입스크립트에서 동작이 다르기 때문에 문자열 열거형은 사용하지 않는 것이 좋다.

👉 열거형 대신 리터럴 타입의 유니온을 사용하면 된다.

type Flavor = "vanilla" | "chocolate" | "strawberry";

let flavor: Flavor = "chocolate"; // 정상
flavor = "mint"; // ❌ 'mint' 유형은 'Flavor' 유형에 할당될 수 없습니다/

👎 타입스크립트에서 매개변수 속성의 문제점

class Person {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}
class Person {
  constructor(public name: string) {}
}

public name은 '매개변수 속성'이라고 불린다.

  • 일반적으로 타입스크립트 컴파일은 타입 제거가 이루어지므로 코드가 줄어들지만, 매개변수 속성은 코드가 늘어나는 문법이다.
  • 매개변수 속성이 런타임에는 실제로 사용되지만, 타입스크립트 관점에서는 사용되지 않는 것처럼 보인다.
  • 매개변수 속성과 일반 속성을 섞어서 사용하면 클래스의 설계가 혼란스러워진다.

👉 클래스에 매개변수 속성만 존재한다면 클래스 대신 인터페이스로 만들고 객체 리터럴을 사용하자

타입스크립트의 역할을 명확하게 하려면 열거형, 매개변수 속성, 트리플 슬래시 임포트, 데코레이터는 사용하지 않는 것이 좋다

[아이템54] 객체를 순회하는 노하우

const obj = {
  one: "uno",
  two: "dos",
  three: "tres",
};
for (const k in obj) {
  const v = obj[k]; // ❌ obj에 인덱스 시그니처가 없기 때문에 엘리먼트는 암시적으로 'any' 타입입니다.
}

오류 발생 이유 : k의 타입은 string인 반면, obj 객체에는 'one', 'two', 'three' 세 개의 키만 존재하기 때문

❓ 왜 k의 타입을 string으로 추론할까?
👉 one, two, three 외에 다른 속성이 존재할 수 있기 때문에 타입스크립트는 obj의 키를 string 타입으로 선택해야 한다.

let k: keyof typeof obj;
for (k in obj) {
  const v = obj[k]; // 정상
}

👍 객체를 순회하며 키와 값을 얻는 가장 일반적인 방법

interface ABC {
  a: string;
  b: string;
  c: number;
}

function foo(abc: ABC) {
  for (const [k, v] of Object.entries(abc)) {
    k; // type : string
    v; // type : any
  }
}
profile
Frontend 개발자입니다 😎

0개의 댓글