javascript - Typescript: Egenskapen finns inte


Jag försöker utveckla en dekoratör för REST API-gränssnitt i Typescript. Här är dekoratörens 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;
    }
}

Nu kan jag använda dekoratorn @RemoteResource och metoderna post|retrieve|remove|update läggs till i det ursprungliga objektets prototyp korrekt.

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

Härifrån, om jag utför

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

Jag har loggen utskriven korrekt, men jag får också följande fel: "Property 'post' does not exist on type 'Foo'." Även om jag förstår varför jag får detta fel (Foo har ingen deklarerad post-egenskap) är jag inte säker på hur jag ska fixa det.

Idealiskt sett skulle jag vilja att TS-kompilatorn förstår att dekoratören utökar det ursprungliga objektet genom att lägga till dessa metoder.

Hur kan jag uppnå det? Några idéer?

Tack!

Svar #1

Eftersom du lägger till dessa metoder dynamiskt vid körning i dekoratorn, har kompilatorn inget sätt att veta att dessa metoder kommer att finnas för Foo-instanser.

Du kan ändra det på olika sätt, till exempel:

(1) Använda ett gränssnitt och en snitt:

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

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

(2) Gränssnitt och tomma metoder:

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

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

Redigera

@Robba föreslår:

(3) Ignorera all typkontroll

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

eller

let tester = new Foo();
tester["post"]();

Relaterade artiklar