[Effective TypeScript] 1장 타입스크립드 알아보기

채동기·2023년 2월 8일
0

TypeScript

목록 보기
1/21

아이템1) 타입스크립트와 자바스크립트 관계이해하기

  • 타입스크립트는 자바스크립트의 상위 집합이다. 모든 자바 스크립트는 타입스크립트이지만, 타입스크립트는 별도의 문법을 가지고 있기 때문에 일반적으로 유효한 자바스크립트 프로그램은 아닙니다.
  • 런타임 오류를 발생시키는 코드를 찾아내지만, 모든 오류를 찾아내지는 못합니다. 타입 체커를 통과해도 오류를 발생시키는 코드는 충분히 존재합니다.
  • 타입스크립트는 전반적으로 자바스크립트 동작을 모델링합니다. 자바스크립트에서는 문제가 되지 않지만, 타입스크립트에서는 문제가 될 수 있습니다. 문법의 엄격함은 취향의 차이이면 우열을 가릴 수 없습니다.

아이템2) 타입스크립트 설정 이해하기

  • 타입 스크립트 설정은 커맨드 라인을 이용하는 것보다 tsconfig.json을 사용하는 것이 좋습니다.
  • 특정 상황이 아니라면 noImplictAny를 설정하는 것이 좋습니다. 설정 하지 않으면 타입을 지정하지 않아도 오류가 발생하지 않습니다.
  • "undefined는 객체가 아닙니다" 와 같은 런타임 오류를 방지하기 위해 strictNullChecks를 설정하는 것이 좋습니다.
  • 위의 두개의 설정을 하고 싶으면 strict을 설정하면 됩니다. strict은 대부분의 오류를 잡아냅니다.

아이템3) 코드 생성과 타입이 관계없음을 이해하기

  • 코드 생성은 타입 시스템과 무관합니다. 타입스크립트 타입은 런타임 동작이나 성능에 영향을 주지 않습니다.
  • 타입 오류가 존재하더라도 컴파일이 가능합니다.
  • 타입 스크립트 타입은 런타임에 사용할 수 없습니다. 런타임에 타입을 지정하려면 타입 정보 유지를 위한 별도의 방법이 필요합니다. 일반적으로는 태그된 유니온 속성 체크 방법을 사용합니다. 또는 클래스 같이 타입 스크립트 타입과 런타임 값, 둘 다 제공하는 방법이 있습니다.

아이템4) 구조적 타이핑에 익숙해지기

  • 자바스크립트가 덕타이핑 기반이고 타입스크립트가 이를 모델링하기 위해 구조적 타이핑을 사용함을 이해해야합니다. 어떤 인터페이스에 할당 가능한 값이라면 타입 선언에 명시적으로 나열된 속성들을 가지고 있을 것입니다. 타입은 '봉인'되어 있지 않습니다.
interface Vector2D {
  x: number;
  y: number;
}
function calculateLength(v: Vector2D) {
  return Math.sqrt(v.x * v.x + v.y * v.y);
}
interface NamedVector {
  name: string;
  x: number;
  y: number;
}
const v: NamedVector = { x: 3, y: 4, name: 'Zee' };
calculateLength(v);  // OK, result is 5

위의 코드처럼 interface가 달라도 정상적으로 동작하는 것을 볼 수 있습니다.
NamedVector가 Vector2D 호환되기 때문입니다.

  • 클래스 역시 구조적 타이핑 규칙을 따릅니다. 클래스의 인스턴스가 예상과 다를 수 있습니다.
  • 구조적 타이핑을 사용하면 유닛 테스트를 쉽게 할 수 있습니다.

아이템5) any 타임 지양하기

  • any 타입에는 안전성이 없습니다.
  • any 는 함수 시그니처를 무시해버립니다.
function calculateAge(birthDate: Date): number {
  // COMPRESS
  return 0;
  // END
}

let birthDate: any = '1990-01-19';
calculateAge(birthDate);  // OK

입력으로 Date 타입을 받아야 했지만 any를 사용해서 무시하게 됩니다.

  • any 타입은 언어 서비스가 적용되지 않습니다.
    타입스크립트의 자동완성 기능과 도움을 받지 못합니다.
interface Person {
  firstName: string;
  last: string;
}
const formatName = (p: Person) => `${p.firstName} ${p.last}`;
const formatNameAny = (p: any) => `${p.first} ${p.last}`;

인터페이스안의 이름이 바뀌어도 any로 하게 되면 타입의 심벌이 바뀌지 않습니다.

  • any타임은 코드 리팩토링 때 버그를 감춥니다.
  • any는 타입 설계를 감춥니다.
  • any는 타입시스템의 신뢰를 떨어뜨립니다.

출처

<이펙티브 타입스크립트> (댄 밴더캅 지음, 장원호 옮김, 인사이트, 2021)

profile
what doesn't kill you makes you stronger

0개의 댓글