Рассмотрим следующий код:
interface CarData{
wheels: number
}
interface PlaneData{
wings: number
}
interface Vehicle{
type: string,
data: CarData | PlaneData
}
function printWheels(data: CarData){
console.log("Number of wheels: " + data.wheels);
}
function printWings(data: PlaneData){
console.log("Number of wings: " + data.wings);
}
let vehicle: Vehicle;
switch (vehicle.type)
{
case "car":
printWheels(vehicle.data);
break;
case "plane":
printWings(vehicle.data);
break;
}
Я получаю ошибку Argument of type 'CarData | PlaneData' is not assignable to parameter of type 'CarData'.
Property 'wheels' is missing in type 'PlaneData' but required in type 'CarData'.
, которая имеет смысл, поскольку не знает, что это за тип данных. Это может быть решено добавлением общего члена, который сообщает тип. Следующий тип кода проверяет правильно:
interface CarData
{
kind: "carData",
wheels: number
}
interface PlaneData
{
kind: "planeData",
wings: number
}
interface Vehicle
{
type: string,
data: CarData | PlaneData
}
function printWheels(data: CarData)
{
console.log("Number of wheels: " + data.wheels);
}
function printWings(data: PlaneData)
{
console.log("Number of wings: " + data.wings);
}
let vehicle: Vehicle;
switch (vehicle.type)
{
case "car":
if (vehicle.data.kind == "carData") printWheels(vehicle.data);
break;
case "plane":
if (vehicle.data.kind == "planeData") printWings(vehicle.data);
break;
}
Но это дает мне дополнительные значения в интерфейсах данных, которые мне не нравятся. Есть ли более элегантный способ сделать это?