TypeScript类装饰器用于创建具有与构造函数相同的类型参数的方法

时间:2017-05-21 16:12:16

标签: javascript typescript ecmascript-6 decorator

在ES6课程中,我发现自己创建了静态create方法,而不是ClassName.create()而不是new ClassName()new ClassName,因为我遇到了一些愚蠢的错误访问新创建的对象的属性;放弃并执行new ClassName.methodCall()而不是(new ClassName).methodCall()。 IMO更清洁,ClassName.create().methodCall()更容易出现愚蠢和难以捕捉的错误。

然而,在每个类上执行此操作都会变得乏味和冗长,所以我想知道是否有办法使用TS / ES6装饰器以便我可以这样做

@Creatable // or @Creatable()
class ClassName {
    constructor(arguments: IArguments) {}
}

将在类上创建一个static create(arguments: IArguments) { return new this(arguments); }方法,具有相同的参数,包括类型。

这是可能的,如果是这样的话?

1 个答案:

答案 0 :(得分:1)

目前无法在TypeScript中使用装饰器轻松添加新方法,而open issue就是这样。

这样做需要使用类型断言,例如:

interface ICreatable<T> extends Function {
  new (): T;
  create: (...args) => T;
}

function Creatable() {
  return function (target) {
    target.create = (...args) => new target(...args);
    return target;
  }
}

@Creatable()
class Foo {...}

(<ICreatable<Foo>>Foo).create(...)

考虑到问题陈述,这是XY问题。虽然省略了构造函数括号是真正的问题。

使用和不使用参数实例化类的无故障方法是

new Foo().bar();
new Foo(1).bar();

而不是

(new Foo).bar();

可选的构造函数括号通常被认为是不礼貌并且在样式指南中被禁止。如果一个习惯导致问题,它可以被认为是坏习惯,应该避免。不要那样做。这里没有create工厂方法的真正需要。