我试图创建一个类型,将不同的枚举类型Map到预期的数据类型,并希望确保我能够通过类型推断找出正确的数据类型。
enum Car {
BMW,
Toyota,
Fiat
}
type CarWithData =
| {
type: Car.BMW;
data: {
doucheFactor: number;
};
}
| {
type: Car.Toyota;
data: {
dadFactor: number;
};
}
| {
type: Car.Fiat;
data: {
dadFactor: number;
};
};
function handleCar(car: CarWithData) {
switch (car.type) {
case Car.BMW:
console.log(`BMW owner found with douche factor of: ${car.data.doucheFactor}`);
console.log(`DadFactor: ${car.data.dadFactor}`); // TypeError as expected / intended;
break;
default:
console.log(`Toyota / Fiat owner found with dad factor of: ${car.data.dadFactor}`);
}
}
function getDadFactor(car: CarWithData): number {
return car.data.dadFactor ?? -1; // Property "dadFactor" does not exist on type CarWithData
}
handleCar({ type: Car.BMW, data: { doucheFactor: 900 } });
getDadFactor({ type: Car.Fiat, data: { dadFactor: 10} });
这个例子说明了我想要完成的事情。它与handleCar
中的switch语句中的类型推断一样工作。但是,getDadFactor
函数抛出TypeError,因为“dadFactor”在类型CarWithData上不存在。我该怎么办?我考虑过用never声明的所有可能字段的类型做一个联合,但这似乎不是一个好的解决方案。
2条答案
按热度按时间jogvjijk1#
最明显的解决方案是先检查
car.type
。但是,如果这不适合你的情况,可能是因为你有太多的情况下,你可以添加自定义类型后卫Assert汽车有
dadFactor
通过执行以下操作:第三个选项是创建一个只有
dadFactor
的汽车的类型。第三个选项中的技巧是用
T extends T
完成的,您可以将其解释为联合中的for循环。playground
作为第三个选项的更通用的版本,我们可以使用另一个通用参数来指示我们正在寻找的
data
的类型:playground
zpgglvta2#
一个可能的解决方案是这样的:
在这里,我们创建一个新类型,其中的数据类型是所有可能数据类型的部分并集。这是不漂亮,难以阅读,并要求铸造,但确实有正确的功能,我正在寻找。