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

TypeScript: Using typecasting for typeguard

I have class with constructor that can accept object of two types, and then based on what type of object it got, perform different actions.

I’ve seen that it’s possible to use as keyword for that.
But it feels wrong to me.

export type Angle = {
    cos: number; 
    sin: number
}
export type VectorAngleInit = {
    angle: Angle,
    magnitude: number
}
export type VectorDInit = {
    dx: number,
    dy: number
}
export class Vector {
    #dx: number;
    #dy: number;
    constructor(init: VectorAngleInit | VectorDInit) {
        if ((init as VectorAngleInit)?.angle) {
            const angleInit = init as VectorAngleInit
            this.#dx = angleInit.magnitude * angleInit.angle.cos;
            this.#dy = angleInit.magnitude * angleInit.angle.sin;
        } else {
            const dInit = init as VectorDInit
            this.#dx = dInit.dx
            this.#dy = dInit.dy
        }
    }
}

Should i do that another way? If so, which way is better you think?

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

>Solution :

You can use in operator narrowing to check for the presence of "angle" in init and narrow init to the desired union member without a need for type assertions (what you’re calling "casting"):

export class Vector {
  #dx: number;
  #dy: number;
  constructor(init: VectorAngleInit | VectorDInit) {
    if ("angle" in init) {
      this.#dx = init.magnitude * init.angle.cos;
      this.#dy = init.magnitude * init.angle.sin;
    } else {
      this.#dx = init.dx
      this.#dy = init.dy
    }
  }
}

Playground link to code

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