考虑如下:
type BodyTypeA = {
width: number;
height: number;
label: string;
id: string;
importantNumber: number;
// Many other BodyTypeA specific fields
}
type BodyTypeB = {
width: number;
height: number;
}
type BodyTypeC = {
width: number;
height: number;
}
class PhysicsObject {
body: BodyTypeA | BodyTypeB | BodyTypeC
createFromSprite(...) {
this.body = // This is what I use and it will create a BodyTypeA body
}
createFromJson() {
this.body = // This will set body to BodyTypeB body
}
createFromWhatever() {
this.body = // This will set body to BodyTypeC body
}
}
我在记事本上写的,所以可能会有一些问题。
我的问题是,我有一个情况,我的对象是PhysicsObject
的实例。这个PhysicsObject
类和它的类型由第三方库拥有,我不能/不想编辑它们。每个PhysicsObject
都有一个body
-字段,其中有三个可能的BodyTypes
-我不知道为什么,但这就是它。
我基本上只使用createFromSprite
-方法为PhysicsObjects
创建bodies
,该方法为PhysicsObject
创建BodyTypeA
体。
这里的问题是,当我创建一个主体,然后想要设置id
,label
和许多其他领域的主体,我必须通过不断断言physicsObject.body
是类型BodyTypeA
来做到这一点:
let physicsObject = new PhysicsObject();
physicsObject.createFromSprite(...);
(physicsObject.body as BodyTypeA).label = "abc";
(physicsObject.body as BodyTypeA).id = 124;
let saveImportantNumber = (physicsObject.body as BodyTypeA).importantNumber;
...
所以我想知道我是否可以在这里以某种方式坚持类型断言,而不触及任何第三方库代码或类型?
我在找这样的东西:
let physicsObject = new PhysicsObject();
physicsObject.createFromSprite(...);
// Assertion block?
(physicsObject.body as BodyTypeA) {
// No need to spam type assertion
physicsObject.body.label = "abc";
physicsObject.body.id = 124;
let saveImportantNumber = physicsObject.body.importantNumber;
...
}
// Just assert it and persist somehow?
physicsObject.body as BodyTypeA;
// No need to spam type assertion
physicsObject.body.label = "abc";
physicsObject.body.id = 124;
let saveImportantNumber = physicsObject.body.importantNumber;
...
或者是否有其他方法可以做到我不知道的事情?
无论出于什么原因,当用createFromSprite
创建body
时,body
的类型不喜欢"到BodyTypeA
。我不确定这是否是TypeScript应该做的事情,但如果是的话,它不会在这里发生。我相信createFromSprite
并没有完全创建一个BodyTypeA
的主体,而是希望保持它足够通用。但是,id
和label
这样的字段在PhysicsObject.body
上肯定不存在,而CreateFromSprite
是用其他方法创建的。
可以保留变量的类型断言,但不能保留对象属性的类型断言(因为在此期间可能会发生变化)。
const body = physicsObject.body as BodyTypeA;
body.label = "abc";
body.id = 124;
let saveImportantNumber = body.importantNumber;
一种解决方案是将body赋值给它自己的变量,并键入如下:
const body = physicsObject.body as BodyTypeA;
body.label = "abc";
body.id = 124;
游乐场
另一种方法是使用类型谓词,但这确实需要您的createFromSprite
设置id
,但这是一种更安全的方式来做事情:
if (isBodyTypeA(physicsObject.body)) {
physicsObject.body.label = "abc";
physicsObject.body.id = 124;
}
function isBodyTypeA(body: BodyTypeA | BodyTypeB | BodyTypeC): body is BodyTypeA {
return body.hasOwnProperty('id');
}
游乐场