Пользовательское объединение типов - что это и как можно использовать
Помимо объединения примитивных типов данных (например):
type myType = number | string;
… в TypeScript можно делать и объединение пользовательских типов данных:
interface Rectange {
width: number,
height: number
}
interface Circle {
radius: number
}
type Shape = Rectange | Circle;
Более того, пользовательские типы можно связать между собой при помощи общего для всех типов поля:
interface Rectange {
width: number,
height: number,
type: 'rectange'
}
interface Circle {
radius: number,
type: 'circle'
}
type Shape = Rectange | Circle;
… здесь поле type - является таким связующим звеном; такое поле называется дискриминантом.
Прелесть такого объединения типов заключается в том, что можно проверять значение этого поля и в зависимости от результата - выполнять нужное действие. Например, можно создать такую функцию calcArea:
function calcArea(shape: Shape): number {
const { type } = shape;
switch(type) {
case 'rectange':
return shape.width * shape.height;
case 'circle':
return Math.round(Math.PI * shape.radius ** 2);
}
}
… и тогда пример использования этой функции и объединенного типа будет таким:
interface Rectange {
width: number,
height: number,
type: 'rectange'
}
interface Circle {
radius: number,
type: 'circle'
}
type Shape = Rectange | Circle;
function calcArea(shape: Shape): number {
const { type } = shape;
switch(type) {
case 'rectange':
return shape.width * shape.height;
case 'circle':
return Math.round(Math.PI * shape.radius ** 2);
}
}
const rectangle: Rectange = { width: 10, height: 10, type: 'rectange' };
const circle: Circle = { radius: 20, type: 'circle' };
console.log(calcArea(rectangle)); // => 100
console.log(calcArea(circle)); // => 1257