闭包编译器坚持一个值可以是空的,当它不能是

问题描述 投票:0回答:1

我有一个结构,其类型如下。

 /** @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这是一个有效的赋值,应该是空的?

javascript google-closure-compiler
1个回答
1
投票

作为 _ 被声明为一个类(用@constructor),它默认是可空的,类型是 _ 相当于 !_|null. map的返回类型应该是,如果它不能返回null,将是 !Array|!_!Array|_.

你可以在Closure编译器的 "调试器 "操场上用这个来验证不同的。片段,其中转让给 x 允许转让给 y 被拒绝。

/** @constructor */
function _() {}

/** @type {!Array|_} */
let x = null;  // valid

/** @type {!Array|!_} */
let y = null;  // type error
© www.soinside.com 2019 - 2024. All rights reserved.