如何在TypeScript中为类装饰器添加参数?

23
我可以为一个带参数的类创建一个装饰函数。
示例:
@Plugin("My first Plugin")
class myFirstPlugin {
   ...
}

我尝试过这个,但它不起作用:

function Plugin(constructor: Function, name:string){
    console.log("Plugin found: " + name);
}

我在WebStorm中遇到了一个错误:

TS2346:提供的参数与调用目标的任何签名都不匹配

我需要如何编写这个装饰器函数?

2个回答

36

如果您希望您的装饰器接收参数,则您的装饰器函数需要返回实际的装饰器函数:

function PluginDecorator(name: string) {
    return (ctor: Function) => {
        console.log("Plugin found: " + name);
    }
}

@PluginDecorator("My first Plugin")
class myFirstPlugin {}

(在 PlayGround 中查看代码)

我将名称更改为PluginDecorator,因为Plugin已经存在,编译器会对该名称进行投诉。


1
@Mohsen 不要编辑答案以便回复。是的,构造函数被调用,但只有在执行 new myFirstPlugin() 时才会被调用。 - Nitzan Tomer
在这个例子中,“ctor”未定义 - 它不应该指向“myFirstPlugin1”吗? - James
1
@James ctor 不是 undefined,它是 myFirstPlugin。(只需更改为:console.log("找到插件:" + name, ctor); - Nitzan Tomer
这并不是一个非常实质性的答案。使用此实现无法对类执行任何操作。类似于“function decorator<T extends { new( ...args: any[]): {} }>(cTor: T) { return class extends cTor ...”修改类的形式是什么? - roberto tomás

3

如果您需要访问参数和构造函数:

type BaseClass = HTMLElement;

type Constructor = { new (...args: any[]): BaseClass };

export function Plugin(name: string) {
    return function <T extends Constructor>(constructor: T) {
        const cls = class extends constructor {
            // custom implementation here
        };

        // perhaps something like this
        customElements.define(name, cls, { extends: "div" });

        return cls;
    };
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接