[이펙티브 타입스크립트] 아이템48 ~ 아이템50

Yongwoo Cho·2022년 6월 11일
0

TIL

목록 보기
88/98
post-thumbnail

[아이템48] API주석에 TSDoc 사용하기

타입스크립트 언어 서비스가 JSDoc 스타일을 지원하기 때문에 적극적으로 활용하는 것이 좋다. 타입스크립트 관점에서는 TSDoc라고 부르기도 한다.

/**
 *  인사말을 생성합니다.
 *  @param name 인사할 사람의 이름
 *  @param title 그 사람의 칭호
 *  @returns 사람이 보기 좋은 형태의 인사말
 */
function greetFullTSDoc(name: string, title: string) {
  return `Hello ${title} ${name}`;
}

👍 @param과 @returns를 추가하면 함수를 호출하는 부분에서 각 매개변수와 관련된 설명을 보여준다.

[아이템49] 콜백에서 this에 대한 타입 제공하기

class ResetButton {
  render() {
    return makeButton({ text: "Reset", onClick: this.onClick });
  }
  onClick() {
    alert(`Reset ${this}`);
  }
}

❌ onClick을 호출하면 this 바인딩 문제로 인해 "Reset이 정의되지 않았습니다"라는 경고 발생

✔️ 해결책 : 생성자에서 메서드에 this 바인딩 , 화살표 함수 사용

class ResetButton {
  constructor() {
    this.onClick = this.onClick.bind(this);
  }
  render() {
    return makeButton({ text: "Reset", onClick: this.onClick });
  }
  onClick() {
    alert(`Reset ${this}`);
  }
}

class ResetButton {
  render() {
    return makeButton({ text: "Reset", onClick: this.onClick });
  }
  onClick = () => {
    alert(`Reset ${this}`); // this가 항상 인스턴스를 참조
  };
}

typescript에서의 this 바인딩
👉 콜백 함수의 매개변수에 this를 추가하고, 콜백 함수를 call로 호출해서 해결할 수 있음.

function addKeyListener(
  el: HTMLElement,
  fn: (this: HTMLElement, e: KeyboardEvent) => void
) {
  el.addEventListener("keydown", (e) => fn.call(el, e));
}

👍 장점

  • 콜백 함수의 매개변수에 this를 추가하면 this 바인딩이 체크되기 때문에 실수를 방지할 수 있음
  • 라이브러리 사용자의 콜백 함수에서 this를 참조할 수 있고 완전한 타입 안정성을 얻을 수 있음

콜백 함수에서 this 값을 사용해야 한다면 this는 API의 일부가 되는 것이기 때문에 반드시 타입 선언에 포함해야 한다.

[아이템50] 오버로딩 타입보다는 조건부 타입을 사용하기

function double(x: number | string): number | string;
function double(x: any) {
  return x + x;
}

const num = double(2); // type: string | number
const str = double('x'); // type: string | number
❌ 선언이 틀리진 않았지만 모호함
function double<T extends number|string>(x: T): T;
function double(x: any) {
  return x + x;
}

const num = double(2); // type: 2
const str = double('x'); // type: 'x'
❌ 타입이 너무 과하게 구체적
function double(x: number): number;
function double(x: string): string;
function double(x: any) {
  return x + x;
}

const num = double(2); // type: number
const str = double('x'); // type: string
❌ 타입이 명확해졌지만 버그 발생

function f(x:number|string){
  return double(x); // ❌ 'string|number' 형식의 인수는 'string'형식의 매개변수에 할당될 수 없습니다.
}

✔️ 가장 좋은 해결책 : 조건부 타입 사용

function dobule<T extends number | string>(
  x: T
): T extends string ? string : number;

function double(x: any) {
  return x + x;
}
profile
Frontend 개발자입니다 😎

0개의 댓글