【问题标题】:Closure compiler typing: Refer to function (factory method)闭包编译器类型:引用函数(工厂方法)
【发布时间】:2016-05-23 10:46:14
【问题描述】:

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

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
 */

问题:闭包编译器说这与形参不匹配。

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

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

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

我怎样才能为 CC 做到这一点?

【问题讨论】:

    标签: javascript google-closure-compiler


    【解决方案1】:

    一种方法是在 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
     */
    

    【讨论】:

      【解决方案2】:

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

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

      使用松散的函数类型“Function”或“!Function”会如您所愿。

      我用这个定义来验证:

      /** @param {{createFoo: !Function}} options */
      function f(options) {}
      
      f({createFoo: Foo.create});
      

      CC debugger sample

      【讨论】:

        猜你喜欢
        • 2015-07-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-12
        • 2017-06-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多