我一直在使用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'])))))),
^^^^^^^^^^^^^^^^^
您面临的问题是编译器通常以不同方式处理计算和点属性访问。计算属性访问被视为“未知”类型,除非您为类型签名提供[]运算符(即类实现IArrayLike为Array do或IObject [2]用于类似map的对象)。
虽然,编译器可以理解x.foo和x ['foo']引用相同的属性,但它目前不会这样做。
[1] https://github.com/google/closure-compiler/wiki/Special-types-in-the-Closure-Type-System