【发布时间】:2021-06-15 15:17:31
【问题描述】:
我有以下两个接口,一个允许可以为空的vin,另一个不允许:
interface IVehicle {
vin: string | null;
model: string;
}
interface IVehicleNonNullVin {
vin: string;
model: string;
}
我希望能够在我能够推断出vin 不是null 的执行路径中将模型从IVehicle 转换为IVehicleNonNullVin。
考虑这个例子:
const myVehicle: IVehicle = {
vin: 'abc123',
model: 'm3'
};
const needsVin = (_: IVehicleNonNullVin) => false;
if (myVehicle.vin === null) {
throw new Error('null');
} else {
needsVin(myVehicle);
// ~~~~~~~~~~~~~~~~~~~ 'IVehicle' is not assignable to 'IVehicleNonNullVin'
}
返回以下错误:
“IVehicle”类型的参数不能分配给“IVehicleNonNullVin”类型的参数。
属性“vin”的类型不兼容。
键入'字符串 | null' 不可分配给类型 'string'。
类型 'null' 不能分配给类型 'string'。
即使我是肯定的,这里的属性也不能为空。
问:如何通过代码流中的类型检查让TS相信现有模型符合类型?
Demo in TS Playground
解决方法
作为一种解决方法,我可以强制转换类型(但这会忽略现有的类型安全性):
needsVin(myVehicle as IVehicleNonNullVin);
或者建立一个新模型(但这不能很好地扩展很多属性):
const nonNullVehicle: IVehicleNonNullVin = {
model: myVehicle.model,
vin: myVehicle.vin
}
needsVin(nonNullVehicle);
【问题讨论】: