Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is it possible to persist type assertion of a variable, or have a "type assertion block"?

Consider something like this:

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
    }
}

I wrote that on a notepad, so there could be some issues.

My problem is that I have a situation where I have objects which are instances of PhysicsObject. This PhysicsObject class and its typings are owned by a third-party library and I cannot / don’t want to edit them. Every PhysicsObject has a body-field with three possible BodyTypes – I don’t know why, but that’s just how it is.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I am basically only creating bodies for PhysicsObjects with the createFromSprite-method, which creates a BodyTypeA body for the PhysicsObject.

The issue here is that when I create a body and then want to set id, label and many other fields for the body, I have to do it by constantly asserting that the physicsObject.body is of type 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;
...

So I am wondering if I could somehow persist the type assertion here, without touching any of the third-party library code or types?

I am looking for something like this:

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;
...

Or is there some other way to do something like this that I’m not aware of?

For whatever reason when creating the body with createFromSprite, the type of the body doesn’t like "collapse" to BodyTypeA. I am not sure if this is something that TypeScript should do, but if so, it doesn’t happen here. I believe that createFromSprite doesn’t exactly create a BodyTypeA body, but instead wants to keep it general enough. However, fields like id and label definitely don’t exist on PhysicsObject.body created with other methods than CreateFromSprite.

>Solution :

You can persist the type assertion of a variable, but not of an object property (since that might get mutated in the meantime).

const body = physicsObject.body as BodyTypeA;
body.label = "abc";
body.id = 124;
let saveImportantNumber = body.importantNumber;
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading