Closure Compiler不再能够确定类型

时间:2018-08-08 14:12:05

标签: google-closure-compiler

我在大多数项目中都使用了Google的Closure Compiler,其中一些在高级模式下输入了100%。

我的一个项目虽然不再被声明为100%键入,并且我收到了一些我以前不曾为之准备的东西的警告,但我似乎无法弄清楚为什么。这是我收到的消息

WARNING - could not determine the type of this expression
                                                v['children'].map(v => new _ChildLineItem(v['child'], v['option'], v['quantity'], v['price'])))))),
                                                                                                                                  ^

还有42条类似的警告,所有警告都与我在这里使用的相同代码

    /**
     * @constructor
     * @param {Array<!_Quote>} quotes
     * @param {string} email
     * @param {?string} quoteid
     */
    function _GetQuotes(quotes, email, quoteid) {
        this.quotes = quotes;
        this.email = email;
        this.quoteid = quoteid;
    }

    /**
     * @constructor
     * @param {string} quoteid
     * @param {boolean} shipping
     * @param {Array<!_Proof>} proofs
     * @param {Array<!_LineItem>} lineitems
     */
    function _Quote(quoteid, shipping, proofs, lineitems) {
        this.quoteid = quoteid;
        this.shipping = shipping;
        this.proofs = proofs;
        this.lineitems = lineitems;
    }

    /**
     * @constructor
     * @param {string} number
     * @param {string} main
     * @param {string} thumbnail
     */
    function _Proof(number, main, thumbnail) {
        this.number = number;
        this.main = main;
        this.thumbnail = thumbnail;
    }

    /**
     * @constructor
     * @param {string} name
     * @param {number} quantity
     * @param {number} price
     * @param {Array<!_ChildLineItem>} children
     * */
    function _LineItem(name, quantity, price, children) {
        this.name = name;
        this.quantity = quantity;
        this.price = price;
        this.children = children;
    }

    /**
     * @constructor
     * @param {string} child
     * @param {string} option
     * @param {number} quantity
     * @param {number} price
     * */
    function _ChildLineItem(child, option, quantity, price) {
        this.child = child;
        this.option = option;
        this.quantity = quantity;
        this.price = price;
    }

    Ajax({
        url: '/ajax/getquotes',
        data: Data,
        success: function (/** !_GetQuotes */ data) {
            var d = new _GetQuotes(
                data['quotes'].map(v => new _Quote(v['quoteid'], v['shipping'],
                    v['proofs'].map(v => new _Proof(v['number'], v['main'], v['thumbnail'])),
                    v['lineitems'].map(v => new _LineItem(v['name'], v['quantity'], v['price'],
                        v['children'].map(v => new _ChildLineItem(v['child'], v['option'], v['quantity'], v['price'])))))),
                data['email'], data['quoteid']);
    ...

我可以重写闭包以指定像这样通过的对象的类型

v['children'].map(function( /** !_ChildLineItem */ v) { new _ChildLineItem(v['child'], v['option'], v['quantity'], v['price'])}

但是不能从构造函数定义中找出答案吗?


实际上,我像这样指定所有人都没有用

var d = new _GetQuotes(
    data['quotes'].map((/** !_Quote */ v) => new _Quote(v['quoteid'], v['shipping'],
        v['proofs'].map((/** !_Proof */ v) => new _Proof(v['number'], v['main'], v['thumbnail'])),
        v['lineitems'].map((/** !_LineItem */ v) => new _LineItem(v['name'], v['quantity'], v['price'],
            v['children'].map((/** !_ChildLineItem */ v) => new _ChildLineItem(v['child'], v['option'], v['quantity'], v['price'])))))),
    data['email'], data['quoteid']);

收到此警告

WARNING - could not determine the type of this expression
                                                v['children'].map((/** !_ChildLineItem */ v) => new _ChildLineItem(v['child'], v['option'], v['quantity'], v['price'])))))),
                                                ^^^^^^^^^^^^^^^^^

1 个答案:

答案 0 :(得分:0)

您面临的问题是,编译器通常对计算访问和点属性访问的处理方式不同。除非您为类型签名提供[]运算符(即,该类像Array一样实现IArrayLike或对类似地图的对象使用IObject [2]),否则计算的属性访问将被视为“未知”类型。

尽管,编译器可以理解x.foo和x ['foo']引用了相同的属性,但当前不这样做。

[1] https://github.com/google/closure-compiler/wiki/Special-types-in-the-Closure-Type-System