[Effective Typescript Study] week_4

Dae-Hee·2022년 9월 20일
0

Typescript Study

목록 보기
7/11
post-thumbnail

4주차 Item 28 ~ 37


▪︎ Item 28 - 유효한 상태만 표현하는 타입을 지향하기

  • 유효한 상태와 무효한 상태를 둘 다 표현하는 타입은 혼란을 초래하기 쉽고 오류를 유발하게 된다.

  • 역할을 명확하게 나누어 타입을 분리 처리 해야한다.

  • 따라서 코드가 길어지더라도 유효한 상태만 표현하는 타입을 자향해야 한다.


▪︎ Item 29 - 사용할 때는 너그럽게, 생성할 때는 엄격하게

  • 보통 매개변수 타입은 반환 타입에 비해 범위가 넓은 경향이 있다. 선택적 속성과 유니온 타입은 반환 타입보다 매개변수 타입에 더 일반적이다.

  • 매개변수와 반환 타입의 재사용을 위해서 기본 형태(반환 타입)와 느슨한 형태(매개변수 타입)를 도입하는 것이 좋다.


▪︎ Item 30 - 문서에 타입 정보를 쓰지 않기

  • 주석과 변수명에 타입 정보를 적는 것은 피해야한다.

  • 타입 선언이 중복되는 것으로 끝나면 다행이지만 최악의 경우는 타입 정보에 모순이 발생하게 된다.

  • 타입이 명확하지 않은 경우는 변수명에 단위 정보를 포함하는 것을 고려하는 것이 좋다.


▪︎ Item 31 - 타입 주변에 null 값 배치하기

  • 한 값의 null 여부가 다른 값의 null 여부에 암시적으로 관련되도록 설계하면 안된다.

  • API 작성 시에는 반환 타입을 큰 객체로 만들고 반환 타입 전체가 null 이거나 null이 아니게 만들어야 한다.

  • strictNullChecks는 반드시 필요한 타입스크립트 옵션이다.


▪︎ Item 32 - 유니온의 인터페이스보다는 인터페이스의 유니온을 사용하기

  • 유니온 타입의 속성을 여러 개 가지는 인터페이스에서는 속성 간의 관계가 분명하지 않기 때문에 실수가 자주 발생하므로 주의해야 한다.
interface A {
  a: TypeA | TypeB | TypeC
  b: TypeD | TypeE | TypeF
}
// 위 유니온 인터페이스 보다

// 아래의 인터페이스의 유니온을 사용하면 속성끼리 잘못된 조합으로 섞이는 경우를 방지할 수 있다.
interface InterA {
  a: TypeA
  b: TypeD
}
interface InterB {
  a: TypeB
  b: TypeE
}
interface InterC {
  a: TypeC
  b: TypeF
}
type A = InterA | InterB | InterC;
  • 타입스크립트가 제어 흐름을 분석할 수 있도록 타입에 태그를 넣는 것을 고려해야 한다.

▪︎ Item 33 - string 타입보다 더 구체적인 타입 사용하기

  • 문자열을 남발하여 선언된 코드를 피한다. 모든 문자열을 할당할 수 있는 string 타입 보다는 구체적인 타입을 사용하는 것이 좋다.

  • 변수의 범위를 보다 정확하게 표현하고 싶다면 string 타입보다는 문자열 리터럴 타입의 유니온을 사용하면 된다.

  • 객체의 속성이름을 함수 매개변수로 받을때는 string보다 keyof T를 사용하는 것이 좋다.

// 1. 기본
function pluck(records, key) {
  return records.map(r => r[key]);
}

// 2. 함수 시그니처 적용
function pluck(records: any[], key: string): any[] {
  return records.map(r => r[key]);
}

// 3. 제네릭(정밀성) 적용
function pluck<T>(records: T[], key: string): any[] {
  return records.map(r => r[key]); // 오류 발생! (string의 범위가 너무 넓다)
}

// 4. 범위 좁히기
type K = keyof Album; // 타입이 한정적

function pluck<T>(records: T[], key: keyof T): T[keyof T][] {
  return records.map(r => r[key]);
} // key의 값으로 하나의 문자열을 넣게되면 반환 타입 | string이 되어 버린다.

// 5. 다수의 제릭 매개변수와 extends를 활용해 더 좁히기
function pluck<T, K extends keyof T>(records: T[], key: K): T[K][] {
  return records.map(r => r[key]);
}

▪︎ Item 34 - 부정확한 타입보다는 미완성 타입을 사용하기

  • 타입 안전성에서 복잡한 계층형은 피해야 한다.

  • 정확하게 타입을 모델링할 수 없다면 아에 안해야한다.

  • any와 unknown를 구별해서 사용해야한다.

unknown : 뭔지 잘 모르겠으니까 너가 타입을 정확히 지정해줘
any : 쓰면 안되는것...ㅎ
  • 타입 정보를 구체적으로 만들수록 오류 메시지와 자동 완성 기능에 주의를 기울여야 한다.

▪︎ Item 36 - 해당 분야의 용어로 타입 이름 짓기

  • 가독성을 높이고, 추상화 수준을 올리기 위해서 해당 분야의 용어를 정밀하게 사용해야 한다.

  • 같은 의미에 다른 이름을 붙이면 안된다. 특별한 의미가 있을 때만 용어를 구분해야 한다.


▪︎ Item 37 - 공식 명칭에는 상표를 붙이기

  • 타입스크립트는 구조적 타이핑을 사용하기 때문에, 값을 세밀하게 구분하지 못하는 경우가 있다.

  • 값을 구분하기 위해 공식 명칭이 필요하다면 상표를 붙이는 것을 고려해야 한다.

  • 상표 기법은 타입 시스템에서 동작하지만 런타임에 상표를 검사하는 것과 동일한 효과를 얻을 수 있다.


0개의 댓글