我有一个结构,其类型如下。
/** @type {!Array<{
* cmd: string,
* params: !Array<{name: string}>,
* do: function(!Object, !Array<!Roll20Object>, !Array<string>, boolean):string
* }>} */
其中一个加载到结构中的值包括以下字段。
do: ((p,t,r,a) => {
/** @type {!Array<string|number|boolean>} */
let results = _.map(t, x => getTokenAttr(x,p.property));
GetTokenAttr的返回类型是: {null|string|number}
. _.map
在 underscore.js 的 externs 中输入如下。
/**
* Object-style annotation
* @param {Object|Array} obj
* @param {Function} iterator
* @param {Object=} opt_context
* @return {!Array|_}
*/
Closure在编译该结构时给出了以下错误。
pf2utils.js:1029: WARNING - [JSC_TYPE_MISMATCH] initializing variable
found : (Array|_|null)
required: Array<(boolean|number|string)>
let results = _.map(t, x => getTokenAttr(x,p.property));
它似乎在声称 results
有可能 null
但不清楚这是从哪里来的。该 do
宣言承诺 t
参数不是空的(因为它是 !Array<..>
和外部 _.map
承诺,它不会返回null(由于 @return {!Array|_}
). 但Closure是治疗 _.map
归来 (Array|_|null}
而不是,没有提示。
如何告诉Closure这是一个有效的赋值,应该是空的?
作为 _
被声明为一个类(用@constructor),它默认是可空的,类型是 _
相当于 !_|null
. map的返回类型应该是,如果它不能返回null,将是 !Array|!_
不 !Array|_
.
你可以在Closure编译器的 "调试器 "操场上用这个来验证不同的。片段,其中转让给 x
允许转让给 y
被拒绝。
/** @constructor */
function _() {}
/** @type {!Array|_} */
let x = null; // valid
/** @type {!Array|!_} */
let y = null; // type error