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