이펙티브 타입스크립트(5)

남자김용준·2021년 11월 7일
0

아이템21. 타입 넓히기

타입스크립트는 종종 지정된 단일 값을 가지고 할당 가능한 값들의 집합을 유추해내야 한다. 이러한 과정을 '넓히기'라고 한다.

const, 타입 구문, 문맥, as const 사용에 익숙해져야 한다.

let x= 'x'; // string으로 추론
const x = 'x'; // 타입이 'x'

const v = {
  x:1,
}
v.x = 3 // 정상
v.x = '3' // error
v.y = 5 // error

const v1 = {
  x : 1,
  y : 2
} // 타입은 { x : number; y : number; }

const v2 = {
  x : 1 as const,
  y : 2
} // 타입은 { x : 1; y : number; }

const v3 = {
  x : 1,
  y : 2
} as const
// 타입은 { readonly x : 1; readonly y : 2; }

아이템22. 타입 좁히기

타입 좁히기는 타입스크립트가 넓은 타입으로부터 좁은 타입으로 진행하는 과정을 말한다.

const el = document.getElementById('foo'); // 타입이 HTMLElement | null
if(el){
  el // 타입이 HTMLElement
  el.innerHTML = 'Party'.blink();
} else {
  el // 타입이 null
  alert('No element')_;
}

분기문 외에도 여러 종류의 제어 흐름을 살펴보며 타입스크립트가 타입을 좁히는 과정을 이해해야 한다.

태그된/구별된 유니온과 사용자 정의 타입 가드를 사용하여 타입 좁히기 과정을 원할하게 만들 수 있다.

instanceof, Array.isArray, 태그된 유니온 패턴, 사용자 정의 타입 가드

아이템23. 한꺼번에 객체 생성하기

객체의 타입 추론을 위해서 속성을 제각각 추가하지 말고 한꺼번에 만들어야 한다.

안전한 타입으로 속성을 추가하려면 객체 전개 ({...a,...b})를 사용하면 된다.

객체에 조건부로 속성을 추가하는 방법을 익혀야 한다.

declare let hasDates : boolean;
const nameTitle = {name:'TEST', title:'TITLE'};
const pharaoh = {
  ...nameTitle,
  ...(hasDates ? {start: -123, end: -321} : {})
}

cosnt pharaoh : {
  start : number;
  end : number;
  name : string;
  title: string;
} | {
  name: string;
  title: string;
}

아이템24. 일관성 있는 별칭 사용하기

const test = {name:'TEST',location:[1,2]};
const loc = test.location;
loc[0] = 0;
test.location // [0,2]

위의 loc을 별칭이라고 한다. 별칭의 값을 변경하면 원래 속성값에서도 변경된다.

별칭은 타입스크립트가 타입을 좁히는 것을 방해한다. 따라서 변수에 별칭을 사용할 때는 일관되게 사용해야 한다.

interface Coordinate {
  x : number;
  y : number;
}

interface BoundingBox {
  x : [number,number];
  y : [number,number];
}

interface Polygon {
  exterior : Coordinate[];
  holes : Coordinate[];
  bbox?: BoundingBox;
}
function isPointInPolygon(polygon,: Polygon, pt: Coordinate){
  const box = polygon.bbox;
  if(polygon.bbox){
    if(pt.x < box.x[0] || pt.x > box.x[1]) ||
      // ~~~ ~~~ box 객체가 undefined일 수 있음
      // if문에서 타입을 좁힌 건 bbox / box 객체의 타입을 좁히지 않음
  }
};
function isPointInPolygon(polygon,: Polygon, pt: Coordinate){
  const { bbox } = polygon.bbox;
  if(bbox){
    const {x,y} = bbox;
    if(pt.x < x[0] || pt.x > x[1]) ||
  }
}
  

비구조화 문법을 사용해서 일관된 이름을 사용하는 게 좋다.

함수 호출이 객체 속성의 타입 정제를 무효화할 수 있다는 점을 주의해야 한다. 속성보다 지역 변수를 사용하면 타입 정제를 믿을 수 있다.

아이템25. 비동기 코드에는 콜백 대신 async 함수 사용하기

콜백보다는 프로미스를 사용하는 게 코드 작성과 타입 추론면에서 유리하다.

가능하면 프로미스를 생성하기보다는 async와 await을 사용하는 게 좋다.

어떤 함수가 프로미스를 반환한다면 async로 선언하는 게 좋다.

profile
frontend-react

0개의 댓글