Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Property does not exist

I'm trying to develop a decorator for REST Api Interfaces in Typescript. Here it is the decorator implementation

export function RemoteResource(params: any): Function {
    console.log("RemoteResource.params: ", params);
    return function (target: Function) {

        //--POST
        target.prototype.post = function () {
            console.log("----POST");
        };

        //--GET
        target.prototype.retrieve = function () {
            console.log("----GET");
        };

        //--DELETE
        target.prototype.remove = function () {
            console.log("----DELETE");
        };

        //--PULL
        target.prototype.update = function () {
            console.log("----PULL");
        };

        console.log("RemoteResource.target: ", target);

        return target;
    }
}

Now, I can use the decorator @RemoteResource and the methods post|retrieve|remove|update are added to the original object prototype correctly.

@RemoteResource({
    path: "/foos",
    methods: [],
    requireAuth: false
})
export class Foo { }

From here, if I execute

let tester = new Foo();
tester.post() //--This prints out "----POST" correctly

I've the log printed out correctly, but I've also have the following error: "Property 'post' does not exist on type 'Foo'." While I understand why I'm having this error (Foo doesn't have any declared post property) I'm not sure about how to fix it.

Ideally, I would like that the TS compiler understand that the decorator extends the original object adding up those methods.

How can I achieve it? Any ideas?

Thanks!

like image 957
Maurizio Vacca Avatar asked Apr 14 '26 08:04

Maurizio Vacca


1 Answers

Since you are adding these methods dynamically at runtime in the decorator, the compiler has no way of knowing that these methods will exist for Foo instances.

You can change that in different ways, for example:

(1) Using an interface and intersection:

interface RemoteResource {
    post(): void;
    remove(): void;
    update(): void;
    retrieve(): void;
}

let tester = new Foo() as Foo & RemoteResource;
tester.post(); // no error

(2) Interface and empty methods:

export class Foo implements RemoteResource {
    post: () => void;
    remove: () => void;
    update: () => void;
    retrieve: () => void;
}

let tester = new Foo() as Foo & RemoteResource;
tester.post();

Edit

@Robba suggests:

(3) Ignore all type checking

let tester = new Foo() as any;
tester.post();

or

let tester = new Foo();
tester["post"]();
like image 124
Nitzan Tomer Avatar answered Apr 16 '26 20:04

Nitzan Tomer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!