Miles P
Miles P

Reputation: 710

Typescript type checking not working with my decorator

Consider the following method in my Map class:

@XYLiteralDecorator
setCenter(xy: XY | XYLiteral): void {
    this.mapI.centerAt((<XY>xy).projectToPoint(3978));
}

This is the @XYLiteralDecorator decorator used above:

function XYLiteralDecorator(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
    const originalMethod = descriptor.value;
    descriptor.value = function(maybeXY: XY | XYLiteral): XY {
        return originalMethod.apply(this, [isXYLiteral(maybeXY) ? new XY(maybeXY[0], maybeXY[1]) : maybeXY]);
    };
    return descriptor;
}

You'll notice in the setCenter method I need to force xy to be of type XY since TS will complain xy can be either XY or XYLiteral otherwise. However my decorator will always ensure xy is of type XY.

Is it possible for TS to know xy can only be of type XY while at the same time allowing both XY or XYLiteral types to be passed as parameters (without forcing types like I'm doing above)?

Upvotes: 2

Views: 507

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249486

You can add an overload that contains the union type parameter and have the implementation have the actual parameter type:

setCenter(xy: XY | XYLiteral): void;
@XYLiteralDecorator
setCenter(xy: XY ): void {
    console.log(xy.getX());
}

This works as expected, you can call with either type and the implementation will know the actual type:

dds.setCenter(new XY(0,0));
dds.setCenter([1, 1]);

Full sample here

Upvotes: 2

Related Questions