본문으로 건너뛰기

아이템14

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

  • DRY원칙을 지키기 위해선 타입의 중복성을 줄이는 것도 중요하다.

타입 선언을 통한 중복 줄이기

function distance(a: {x: number, y: number}, b: {x: number, y: number}) {
// do something...
}

type Point2D = {
x: number;
y: number;
}

function distance2(a: Point2D, b: Point2D) {
// do something...
}

연산자를 이용한 타입의 확장

type Point2D = {
x: number;
y: number;
}

type Point3D = {
x: number;
y: number;
z: number;
}


type Point3D = Point2D & {
z: number;
}

interface IPoint3D extends Point2D {
z: number;
}

인덱싱을 통합 타입 축소

interface State {
userId: string
pageTitle: string
recentFiles: string[]
pageContents: string
}

type TopNavState = {
userId: State["userId"]
pageTitle: State["pageTitle"]
recentFiles: State["recentFiles"]
}

// 매핑된 타입을 이용한 추상화 추가
type TopNavState = {
[k in "userId" | "pageTitle" | "recentFiles"]: State[k]
}
  • in은 객체의 속성이 있는지 확인하는 연산자이다.
  • of는 제네럭 타입 내의 타입 추론이다.

keyof 연산자와 제네릭을 통해 유틸리티 타입을 만들 수 도있다.

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

type TopNavState = CustomPick<State, "userId" | "pageTitle" | "recentFiles">;

기존의 타입을 optional하게 바꾸고 싶다면

  • Partial을 이용할 수 있다.
// 유틸리티 타입 Partial은 이렇게 생겼습니다.
type Partial<T> = { [k in keyof T]?: T[k] };

type Something = {
a: number;
b: number;
};

type OptionalSomething = Partial<Something>;