책 정리/이펙티브 타입스크립트

아이템 14 타입 연산과 제너릭 사용으로 반복 줄이기

2023. 7. 26. 14:32
목차
  1. 확장해서 반복 제거하는 방법
  2. 매핑된 타입을 사용하는 방법
  3. Pick 사용하는 방법
  4. 태그된 유니온의 타입 중복 제거
  5. 선택적 필드에 대한 중복 제거
  6. Partical 사용하는 방법
  7. 값의 형태에 해당하는 타입을 정의 하고 싶을 때
  8. 함수나 메서드의 반환 값에 명명된 타입을 만들고 싶을 때
  9. 제너릭 타입
  • DRY: 같은 코드를 반복하지 마라
  • 타입에서 중복이 더 흔한 이유 중 하나는 공유된 패턴을 제거하는 메커니즘이 기존 코드에서 하던 것과 비교해 덜 익숙하기 때문
  • 반복을 줄이는 가장 간단한 방법 → 타입에 이름을 붙이는 것
  • 중복된 타입은 종종 문법에 의해서 가려지기도 함

확장해서 반복 제거하는 방법

  • 두 인터페이스가 필드의 부분 집합을 공유한다면, 공통 필드만 골라서 기반 클래스로 분리 가능
interface Person {
	firstNmae: string;
	lastName: sring;
}
interface PersonWithBirthDate extends Person {
	birth: Date;
}
interface PersonWithAge extends Person {
	age: number;
}
  • 이미 존재하는 타입을 확장하는 경우 → 인터섹션 연산자(&) //흔하지 않음
    • 유니온 타입에 속성을 추가할 때 유용함(유니온 타입은 확장 X)
    type PersonWithBirthDate = Person & {birth: Date};
    
  • State를 인덱싱하여 속성의 타입에서 중복을 제거하는 방법
  • interface State { userId: string; pageTitle: string; recenFiles: string[]; pageContents: string; } type TopNavState = { userId: State["userId"]; pageTitle: State["pageTitle"]; recentFiles: State["recentFiles"]; }

매핑된 타입을 사용하는 방법

  • 매핑된 타입은 배열의 필드를 루프 도는 것과 같은 방식
  • 이 패턴은 Pick이라고 표준 라이브러리에 있음.
type TopNavState = {
	[k in "userId" | "pageTitle" | "recenFiles"]: State[k]
};

Pick 사용하는 방법

  • Pick은 제네릭 타입. Pick을 사용하는 것은 함수를 호출하는 것과 마찬가지
  • Pick은 T와 K 두가지 타입을 받아서 결과를 타입을 반환
type Pick<T, K>  = {[k in K]: T[k]}; //기본형

type TopNavState = Pick<State,  "userId" | "pageTitle" | "recenFiles">;

 

태그된 유니온의 타입 중복 제거

  • 유니온 인덱싱
  • ActionType은 Pick을 사용하여 얻게 되는, type 속성을 가지는 인터페이스와 다름
interface SaveAction {
	type: "save";
	...
}
interface LoadAction {
	type: "load";
	...
}
type Action = SaveAction | LoadAction;
type ActionType = Action["type"];/// === type a = "save" | "load";

선택적 필드에 대한 중복 제거

  • 매핑된 타입과 keyof을 사용
    • 이 패턴은 Partical이고 표준 라이브러리에 있음
interface Options {
	width: number;
	height: number;
	color: string;
	label: string;
}
type OptionsUpdate = {[k in keyof Options]?: Options[k]};
  • keyof은 타입을 받아서 속성 타입의 유니온을 반환
type OptionsKeys = keyof Options; // 타입이 "width"|"height"|"color"|"label"

 

Partical 사용하는 방법

  • 특정 타입의 부분 집합을 만족하는 타입을 정의할 수 있다.
type Partial<T> = {[p in keyof T]? = T[p]}; //기본형(필수를 옵셔널로)
type Partial<T> = {[p in keyof T]-? = T[p]}; // 옵셔널을 필수로 만들기
function updateOptionItem(OptionsUpdate: Partial<Options>) { ... }

 

값의 형태에 해당하는 타입을 정의 하고 싶을 때

  • 여기에서 typeof는 런타임 연산자가 아닌 타입스크립트 단계에서 연산된다
    • 훨씬 더 정확하게 타입을 표현
  • 사용 시 선언의 순서에 주의해야
    • 타입 정의를 먼저 하고 값이 그 타입에 할당 가능하다고 선언.
    → 타입이 더 명확해지고, 예상하기 어려운 타입 변동 방지 가능
const INIT_OPTIONS = {
	width: 60;
	height: 40;
	color: "#00FF00";
	label: "VGA"
}
type Options = typeof INIT_OPTIONS;

함수나 메서드의 반환 값에 명명된 타입을 만들고 싶을 때

  • 조건부 타입이 필요함 → ReturnType 제너릭 사용(표준 라이브러리에 있음)
  • ReturnType은 함수의 값이 아니라 타입에 적용된다.
    • 적용 대상이 값인지, 타입인지 정확하게 구분&처리
function getUserInfo(userId: string) {
	...
	return { userId, name, age, height, weight}; //이걸 타입으로 만들고 싶음
}
type UserInfo = ReturnType<typeof getUserInfo>;

제너릭 타입

  • 제너릭 타입은 타입을 위한 함수
    • 제너릭 타입에서 매개변수를 제한할 수 있는 방법이 필요함
    • 제너릭 타입에서 매개변수를 제한할 수 있는 방법은 extends를 사용하는 것
  • 타입스크립트가 제너릭 매개변수의 타입을 추론하게 하기 위해, 함수를 작성할 때 신중하게 타입을 고려해야함
  • Pick함수에서 K는 범위가 너무 넓음
    • K는 실제로 T의 키의 부분집합(keyof T)가 되어야
    • 타입이 값의 집합이라는 관점에서 생각하면 extends가 확장이 아닌 부분집합
type Pick<T, K>  = {[k in K]: T[k]}; 

->

type Pick<T, K extends keyof T> = {[k in K]: T[k]}; 

→ 이 모든 과정의 목표는 유효한 프로그램은 통과시키고 무효한 프로그램에는 오류를 발생시키는 것.

저작자표시 비영리 변경금지 (새창열림)

'책 정리 > 이펙티브 타입스크립트' 카테고리의 다른 글

아이템 41 any의 진화를 이해하기  (0) 2023.07.26
아이템 40 함수 안으로 타입 단언문 감추기  (0) 2023.07.26
아이템 26 타입 추론에 문맥이 어떻게 사용되는지 이해하기  (0) 2023.07.26
아이템 25 비동기 코드에는 콜백 대신 async 함수 사용하기  (0) 2023.07.26
아이템 13 타입과 인터페이스의 차이점 알기  (0) 2023.07.26
  1. 확장해서 반복 제거하는 방법
  2. 매핑된 타입을 사용하는 방법
  3. Pick 사용하는 방법
  4. 태그된 유니온의 타입 중복 제거
  5. 선택적 필드에 대한 중복 제거
  6. Partical 사용하는 방법
  7. 값의 형태에 해당하는 타입을 정의 하고 싶을 때
  8. 함수나 메서드의 반환 값에 명명된 타입을 만들고 싶을 때
  9. 제너릭 타입
'책 정리/이펙티브 타입스크립트' 카테고리의 다른 글
  • 아이템 40 함수 안으로 타입 단언문 감추기
  • 아이템 26 타입 추론에 문맥이 어떻게 사용되는지 이해하기
  • 아이템 25 비동기 코드에는 콜백 대신 async 함수 사용하기
  • 아이템 13 타입과 인터페이스의 차이점 알기
Rulu_
Rulu_
벨로그가 보기 편해요!! 티스토리는 md파일 그대로 복붙해서 올립니다ㅎ https://velog.io/@hafnium1923
루루의 개발 일지 벨로그가 보기 편해요!! 티스토리는 md파일 그대로 복붙해서 올립니다ㅎ https://velog.io/@hafnium1923
Rulu_
루루의 개발 일지
Rulu_
전체
오늘
어제
  • 분류 전체보기 (61)
    • FE 기술 (28)
      • JavaScript (6)
      • React (9)
      • React Native (2)
      • Technic (7)
      • CSS (4)
    • BE 기술 (1)
    • 책 정리 (0)
      • 코어 자바스크립트 (7)
      • 이펙티브 타입스크립트 (6)
    • 우아한 테크 코스 회고 (14)
      • 프리코스 후기 (5)
      • 레벨 1 (2)
      • 레벨 2 (2)
      • 레벨 3 (5)
    • 우아한 테크 코스 피드백 (1)
      • 레벨 1 (1)
      • 레벨 2 (0)
    • 우아한 테크 코스 생활 (3)
      • 생활 이모저모 (1)
      • 글쓰기 (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 테코톡준비자료
  • props 여러개
  • input 컴포넌트
  • react
  • 회고
  • spread operator
  • 레벨로그
  • 재사용 컴포넌트
  • 테코톡
  • 한달생활기
  • 프론트
  • 우아한테크코스후기
  • 레벨인터뷰
  • input 여러개
  • 우아한테크코스
  • 5기

최근 댓글

최근 글

hELLO · Designed By 정상우.
Rulu_
아이템 14 타입 연산과 제너릭 사용으로 반복 줄이기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.