TS/이펙티브 타입스크립트
인터페이스의 유니온 사용하기
5_hyun
2023. 3. 27. 17:58
반응형
유니온의 인터페이스보다는 인터페이스의 유니온을 지향하는 것이 좋다. 사실 앞 문장만 딱 보면 좀 헷갈릴 수 있다. 하지만 막상 코드를 보면 익숙할 것이다.
백터를 그리는 프로그램 작성 예제
유니온의 인터페이스
interface Layer {
layout: FillLayout | LineLayout | PointLayout;
paint: FillPaint | LinePaint | PointPaint;
}
이 코드는 유니온의 인터페이스이다. layout은 모양이 그려지는 방법, 위치를 제어하고, paint는 선의 스타일을 제어한다. 두 속성은 Fill, Line, Point 3개 중 하나를 통일해서 가져야 한다. 하지만 layout은 FillLayout, paint는 LinePaint로 하면 에러가 나게 될 것이다. 그렇기에 더 나은 모델링을 하기 위해서 각 타입을 계층으로 분리하여 인터페이스로 둬야한다.
인터페이스의 유니온
interface FillLayer {
layout: FillLayout
paint: FillPaint
}
interface LineLayer {
layout: LineLayout
paint: LinePaint
}
interface PointLayer {
layout: PointLayout
paint: PointPaint
}
type Layer = FillLayer | LineLayer | PointLayer
이렇게 정의하면 조합이 잘못되는 경우를 방지할 수 있다. 이러한 패턴의 일반적인 예시는 태그 된 유니온 기법이다.
-태그 된 유니온
interface FillLayer {
type: 'fill'
layout: FillLayout
paint: FillPaint
}
interface LineLayer {
type: 'line'
layout: LineLayout
paint: LinePaint
}
interface PointLayer {
type: 'paint'
layout: PointLayout
paint: PointPaint
}
type Layer = FillLayer | LineLayer | PointLayer
type은 태그이고 런타임에 어떤 타입의 Layer가 사용되는지 판단할 수 있다. TS는 타입을 참고해 타입의 범위를 좁힐 수 있다.
function drawLayer(layer: Layer) {
if (layer.type === 'fill') {
const { paint } = layer // Type is FillPaint
const { layout } = layer // Type is FillLayout
} else if (layer.type === 'line') {
const { paint } = layer // Type is LinePaint
const { layout } = layer // Type is LineLayout
} else {
const { paint } = layer // Type is PointPaint
const { layout } = layer // Type is PointLayout
}
}
이렇게 타입의 범위를 좁힐 수 있어 태그된 유니온 기법은 유용하다. 태그된 유니온은 타입스크립트 타입 체커와 잘 맞고 이 패턴을 잘 적용할 수 있어야 한다. 어떤 데이터 타입을 태그된 유니온 기법으로 표현할 수 있으면 보통 하는 것이 좋다.
-여러 개의 필드가 동시에 있거나 없는 경우
interface Person {
name: string
// These will either both be present or not be present
placeOfBirth?: string
dateOfBirth?: Date
}
여러 개의 속성이 상황에 따라 모두 있거나 모두 없어야 하면 숙달되지 않은 사람은 위 코드처럼 모델링할 것이다.
interface Person {
name: string
birth?: {
place: string
date: Date
}
}
이렇게 여러 개의 속성을 한 객체에 모으는 것이 더 좋은 설계이다.
반응형