[Effective Typescript Study] week_3

Dae-Hee·2022년 9월 13일
0

Typescript Study

목록 보기
6/11
post-thumbnail

3주차 Item 19 ~ 27


▪︎ Item 19 - 추론 가능한 타입을 사용해 장황한 코드 방지하기

  • 타입스크립트가 타입을 추론할 수 있다면 타입 구문을 작성하지 않는게 좋다.

  • 이상적인 경우 함수의 시그니처에는 타입 구문이 있지만, 함수 내의 지역변수에는 타입 구문이 없다.

  • 내부 구현의 오류가 사용자 코드 위치에 나타내는 것을 방지하기 위해 추론될 수 있는 경우라도 객체 리터럴과 함수 반환에는 타입 명시를 고려해야 한다.


▪︎ Item 20 - 다른 타입에는 다른 변수 사용하기

  • 자바스크립트에서 let 키워드로 변수를 선언한다면 값은 바뀔 수 있지만 타입은 일반적으로 바뀌지 않는다.

  • 혼란을 막기 위해 타입이 다른 값을 다룰 때에는 변수를 재사용하지 않고 되도록 const로 변수를 선언한다.


▪︎ Item 21 - 타입 넓히기

  • 타입스크립트가 넓히기를 통해 상수의 타입을 추론하는 법을 이해해야 한다.
  // 명시적 타입 구문 제공
  const v = {
    x: 1,
  } // 타입 : { x: number }
  v.x = 3;
  v.x = '3'; // 오류 발생
  
  const v: { x: 1|3|5 } = {
    x: 1,
  } // 타입 : { x: 1|3|5 }
  
  // const 단언문 사용
  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; }
  • 값 뒤에 as const를 작성하면 타입스크립트는 최대한 좁은 타입으로 추론한다.
  • 배열을 튜플 타입으로 추론할 때에도 사용
  const a1 = [1, 2, 3]; // 타입 : number[]
  const a2 = [1, 2, 3] as const; // 타입 : readonly [1, 2, 3]
  • 넓히기로 인해 오류가 발생한다면 명시적 타입 구문 또는 const as 단언문을 추가하는 것을 고려한다.

▪︎ Item 22 - 타입 좁히기

  • 타입스크립트는 일반적으로 조건문에서 타입을 좁히는 데 능숙하다.
  const el = doument.getElementById('foo'); // 타입 : HTMLElement | null
  if (el) {
    // 타입 : HTMLElement
  } else {
    // 타입 : null
  }
  • 명시적 태그를 붙이는 커스텀 함수를 도입 하는 것 타입을 좁히는 데 효과적이다.
  interface UploadEvent { type: 'up'; ... }
  interface DonwloadEvent { type: 'donw'; ... }
  type AppEvent = UploadEvent | DonwloadEvent;
  function handleEvent(e: AppEvent) {
    switch (e.type) {
      case 'down':
        e // 타입 : DonwloadEvent
        break;
      case 'up':
        e // 타입 : UploadEvent
        break;
    }
  }
  • 이러한 기법을 '사용자 정의 타입 가드' 라고 한다.

▪︎ Item 23 - 한꺼번에 객체 생성하기

  • 타입스크립트에서 객체는 속성을 제각각 추가하지말고 한꺼번에 만들어야한다.

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

  • 객체 전개를 통해 속성을 추가할때 여러 속성을 추가할 경우 헬퍼 함수를 적절하게 사용하지 않는다면 타입이 유니온으로 추론된다.

  function addOptional<T extends object, U extends object>(
    a: T, b: U | null
  ): T & Partia<U> {
    return {...a, ...b};
  }

▪︎ Item 24 - 일관성 있는 별칭 사용하기

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

  • 비구조화 문법을 사용하는 것이 일관된 이름을 사용하는데 도움을 준다.

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


▪︎ Item 25 - 비동기 코드에는 콜백 대신 async 함수 사용하기

  • 코드 퀄리티 뿐만아니라 타입 추론 면에서 콜백보다는 프로미스를 프로미스보다는 async/await를 사용하는 것이 좋다.

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


▪︎ Item 26 - 타입 추론에 문맥이 어떻게 사용되는지 이해하기

  • 함수의 매개변수의 타입이 string 이라면 변수로 선언된 분리된 값을 할당하는 것이 불가능하다.
  type A = 'JavaScript';
  function setA(a: A) { /*...*/ }

  setA('JavaScript') // 정상

  let aa = 'JavaScript';
  setA(aa); // 오류
  
  const bb = 'JavaScript';
  setA(bb); // 정상
  • 이는 const(상수 변수 선언 키워드)를 사용해 해결 할 수 있다.


  • 문자열 리터럴 타입과 마찬가지로 튜플 타입에서도 문제가 발생한다.

  function panToBefore(a: [number, number]) { /*...*/ }

  panToBefore([1, 2]); // 정상

  const loc = [1, 2];
  panToBefore(loc); // 오류

  // -----------------------------------------------------------

  function panToAfter(a: readonly [number, number]) { /*...*/ }
  const loc = [1, 2] as const
  panToAfter(loc); // 정상
  • 이는 readonlyas const 를 사용해 해결 할 수 있다.
  • 변수가 정말 상수라면 상수 단언(as const)을 사용해야한다.
  • 그러나 상수 단언을 사용하면 정의한 곳이 아니라 사용한 곳에서 오류가 발생하므로 주의해야한다.

▪︎ Item 27 - 함수형 기법과 라이브러리로 타입 흐름 유지하기

  • 타입 흐름을 개선하고, 가독성을 높이고, 명시적인 타입 구문의 필요성을 줄이기 위해 직접 구현하기보다는 내장된 함수형 기법과 로대시 같은 유틸리티 라이브러리를 사용하는 것이 좋습니다.

로대시?

JavaScript에서 배열 안의 객체들의 값을 handling(배열, 객체 및 문자열 반복 / 복합적인 함수 생성) 할 때 유용한 라이브러리

0개의 댓글