闭包编译器输入:参考函数(工厂方法)

时间:2016-03-31 00:48:28

标签: javascript google-closure-compiler

假设我有一个带有工厂方法的类:

export class Foo {
    constructor(options) {
        this.a = options.a;
        this.b = options.b;
    }

    /**
     * @param {{
     *   a: number,
     *   b: number
     * }} options
     * @return {!Foo}
     */
    static create(options) {
        return new Foo(options);
    }
}

我希望依赖注入Foo的工厂方法在另一个类中,例如:

/**
 * @param {{
 *   createFoo: !function(!Object): !Foo
 * }} options
 */

问题:Closure编译器说这与形式参数不匹配。

found   : {
  createFoo: function ({a: number, b: number): Foo, 
}

required: {
  createFoo: function (Object): Foo, 
}

显然我可以在记录中重写类型签名和硬编码,但我真的想引用Foo.create所以每次添加新参数时都不需要更新整个代码库选项对象。

我怎样才能为CC做这个?

2 个答案:

答案 0 :(得分:3)

一种方法是在typedef中写入一次类型,然后在两个地方引用它。 (我还没试过这个,但我认为它应该有用)

/** @typedef {function({a: number, b:number}): Foo} */
var FooCreator;

export class Foo {
    ...

    /**
     * @type {FooCreator}
     */
    static create(options) {
        return new Foo(options);
    }
}

/**
 * @param {{
 *   createFoo: FooCreator
 * }} options
 */

答案 1 :(得分:2)

一般问题是你需要的函数比Foo.create方法更容易接受。尼克桑托斯写了一个很好的解释:

http://closuretools.blogspot.com/2012/06/subtyping-functions-without-poking-your.html

使用松散的函数类型“函数”或“!函数”将按预期工作。

我用这个定义来验证:

/** @param {{createFoo: !Function}} options */
function f(options) {}

f({createFoo: Foo.create});

CC debugger sample