유니온 타입
하나 이상의 타입을 허용하는 타입
변수, 함수 매개변수, 반환값 등에 대해 서로 다른 여러 타입을 지정
기본문법
let val: string | number;
val = "안녕하세요"; // 문자열 허용
val = 123; // 숫자 허용
// 값 = true; // 오류: 'boolean'은 허용되지 않음
console.log(val);
공통 필드 유니온
타입을 합칠 때 특정 필드나 속성이 공통적으로 존재하는 경우, 타입 간 관계를 정의하거나 유연한 타입을 생성
예시
type traffic= { model: string };
type taxi = traffic & { "hyundai": string };
type bus = traffic & { "kia": string };
type Car = taxi | bus;
활용
// 공통 필드로 타입 좁히기
function getCarInfo(car: Car) {
console.log(`Car model: ${car.model}`); // 공통 필드 사용 가능
if ('hyundai' in car) {
console.log(`This is a Taxi. model: ${car.model}`);
} else if ('kia' in car) {
console.log(`This is a Bus. model: ${car.model}`);
}
}
const taxi: Car = { model: "sonata", hyundai: "taxi-model" };
const bus: Car = { model: "granbird", kia: "bus-model" };
getCarInfo(taxi);
getCarInfo(bus);
유니온 구별
구별하는 기준 : 공통된 속성
type AngleShape =
| { kind: "circle"; radius: number }
| { kind: "square"; sideLength: number }
| { kind: "rectangle"; width: number; height: number };
해당 코드에서는 kind 속성
구별 방법
// 1. switch문
function getArea(shape: AngleShape): number {
switch (shape.kind) {
case "circle":
const circleArea = Math.PI * shape.radius ** 2;
console.log(`Circle Area: ${circleArea}`);
return circleArea
case "square":
return shape.sideLength ** 2;
case "rectangle":
return shape.width * shape.height;
// efault 케이스의 never 타입: 유니온의 모든 멤버가 처리되었는지 확인하는 역할
default:
// TypeScript의 Exhaustiveness 체크
const _exhaustive: never = shape;
throw new Error(`Unknown shape: ${_exhaustive}`);
}
} // 잘못된 멤버가 있을 경우 컴파일 타임에 에러를 발생
getArea({ kind: "circle", radius: 5 });
// 2. if문을 사용한 구별
function getShapeInfo(shape: AngleShape): string {
if (shape.kind === "circle") {
const comment = `Circle with radius ${shape.radius}`;
console.log(comment);
return comment;
} else if (shape.kind === "square") {
return `Square with side length ${shape.sideLength}`;
} else {
// 자동으로 rectangle로 좁혀짐
return `Rectangle with width ${shape.width} and height ${shape.height}`;
}
}
getShapeInfo({ kind: "circle", radius: 3 });
// 3. in 연산자 사용
function describeShape(shape: AngleShape): string {
if ("radius" in shape) {
const message = `Circle with radius ${shape.radius}`;
console.log(message);
return message;
} else if ("sideLength" in shape) {
return `Square with side length ${shape.sideLength}`;
} else {
return `Rectangle with width ${shape.width} and height ${shape.height}`;
}
}
describeShape({ kind: "circle", radius: 7 });
// 4. 커스텀 정의 타입
function isCircle(shape: AngleShape): shape is { kind: "circle"; radius: number } {
return shape.kind === "circle";
}
function getCircleInfo(shape: AngleShape): string {
if (isCircle(shape)) {
return `Circle with radius ${shape.radius}`;
}
return "Not a circle";
}