하나의 인터페이스안에서 값의 타입을 유니온으로 사용하는 것
interface Layer {
/** 모형의 shape */
layout: FillLayout | LineLayout | PointLayout;
/** 모형의 스타일 */
paint: FillPaint | LinePaint | PointPaint;
}
Layer
라는 인터페이스안에 한개 이상의 layout과 paint의 속성이 존재한다.
이 때,layout
이 직선이고 paint
가 fill이라면 오류가 발생하는 상황이지만
현재 유니온의 인터페이스 방식으로는 속성 간의 관계가 명확하지 않기 때문에 미리 오류를 방지하기 어렵다.
태그된 유니온을 이용하여 속성 간의 관계를 명확하게 만들었다.
태그된 유니온 (Tagged Union) 이란
상황에 따라 인터페이스를 분리한 후 해당 인터페이스들을type
을 이용하여 유니온으로 사용한 것
태그는type
에 주어진 개별 속성이며 런타임 시 타입의 범위를 줄일 수 있도록 도와준다
type Layer = FillLayer | LineLayer | PointLayer;
interface FillLayer {
layout: FillLayout;
paint: FillPaint;
}
interface LineLayer {
layout: LineLayout;
paint: LinePaint;
}
interface PointLayer {
layout: PointLayout;
paint: PointPaint;
}
Layer
type에 세개의 인터페이스가 세부화되어 유니언으로 명시되었다.
이러한 방법은 아이템 28(비행기 조종, 기장 사고 방지)에서도 지향했던 방식과 동일한 맥락인데
속성이 잘못된 조합으로 섞이는 경우를 방지하고 유효한 상태만을 표현할 수 있도록 되어있다.
type Layer = FillLayer | LineLayer
interface FillLayer {
kind: 'Fill'; // 태그
layout: FillLayout;
paint: FillPaint;
}
interface LineLayer {
kind: 'Line'; // 태그
layout: LineLayout;
paint: LinePaint;
}
function drawLayer(layer: Layer) {
if (layer.kind === 'fill') { // 태그를 이용하여 분기 처리
const { layout, paint } = layer // 타입은 FillLayout, FillPaint
} else if (layer.kind ==== 'Line') {
const { layout, paint } = layer // 타입은 LineLayout, LinePaint
}
}
단점: 코드가 어수선해 보일 수 있다.
첫번째 시도
- 주석으로만 설명되어 있으므로 오류날 가능성이 있다.
interface Person {
name: string;
// 아래 값은 둘 다 있거나 둘 다 없습니다.
placeOfBirth?: string;
dateOfBirth?: Date;
}
두번째 시도
- birth 에서 place만 있고 date가 없을 경우 오류가 난다.
interface Person {
name: string;
birth?: {
place: string; // place마
date: Date;
}
}
interface name {
name: string;
// 아래 값은 둘 다 있거나 둘 다 없습니다.
placeOfBirth?: string;
dateOfBirth?: Date;
}
왜냐하면 type 속성은 타입스크립트에서 태그로 쓰이며 런타임 시 타입스크립트가 타입을 판단할 때 도움을 주기 때문에 유용, 잘 어울림
특징