我有这些接口:
interface BasicThing {
someType: string
property0: string
}
interface SpecificThing1 extends BasicThing {
someType: 'special1'
property1: number
}
interface SpecificThing2 extends BasicThing {
someType: 'special2'
color: string
}
在我的代码中我有这个变量
let myThing: BasicThing
稍后我将分配给其中一个SpecificThing1
或SpecificThing2
(或其他)。
现在,如果我想要一个SpecificThing1
分配,我可以这样做:
myThing = {
someType: 'special1',
property0: 'asdf',
property1: 42
} as SpecificThing1
但是这样做,如果我为属性分配了错误的类型(如property1: '42' // string is not compatible with number
),我只会得到输入错误,但缺少属性根本不会引发任何错误:
myThing = {
someType: 'special1',
property0: 'asdf'
// property1 is missing here, but no typing errors
} as SpecificThing1
解决此问题的一种黑客方法是:
myThing = ((): SpecificThing1 => {
return {
someType: 'special1',
property0: 'asdf',
// property1: 123 // Now we get the typing error: 'property1 is missing in type...'
}
})()
但这看起来不太好,创建一个作用域只是为了获得该对象的正确类型感觉不太对。
是否可以在创建对象时为对象分配类型,而不仅仅是在接收端?难道这不能以更优雅的方式进行吗?
您可以使用联合类型而不是基类型。效果几乎相同,您将可以访问属于其中的属性的公共属性BaseThing
(尽管如果派生类型具有它们,您可能会获得其他公共属性)
let d2: SpecificThing1 | SpecificThing2 = {
someType: 'special1',
property0: '0',
property1: 1
}
let based: BasicThing = d2;
另一种解决方案是定义一个中间变量,永远不要直接分配基类型的变量
let o: SpecificThing1 = {
someType: 'special1',
property0: '0',
property1: 1
}, d: BasicThing = o;
另一种选择是定义一个辅助函数,您可以在其中指定泛型参数,并且检查将按预期执行:
const literal = <T>(o: T) => o;
let d: BasicThing = literal<SpecificThing1>({
someType: 'special1',
property0: '0',
property1: 1
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句