【问题标题】:Google Closure Compiler type annotations for array数组的 Google Closure Compiler 类型注释
【发布时间】:2011-10-25 08:31:38
【问题描述】:

在使用 Google Closure Compiler 时,我发现了一个无法强制编译器针对错误变量类型发出警告的情况。我使用了以下示例:

/** @typedef ({name: string, token: string}) */
var pendingItem;

/** @type (Array.<pendingItem>) */
var pending = [];

// NOTICE: the token is intentionally misspelled as "toke" to cause a warning
var dummyItem = {
  name: 'NameHere',
  toke: 'SomeToken' 
};

// This should cause a warning, because of the 
// type mismatch (toke instead of token)
pending.push(dummyItem);

// Do something useful so that the whole code wouldn't be optimized to 0 bytes
alert(pending.length);

而且它编译完美,而不是给出预期的类型警告。但如果你使用:

pending[1] = {
  name: 'Second Name',
  toke: 'Second Token'
}

您会收到预期的类型不匹配警告。

我知道这可能是因为push 没有定义类型检查,因为它是一个内置函数。预计将pending 定义为pendingItem 的数组会强制它,但默认情况下不会。

问题是是否以及如何向已经定义的函数(例如push)添加类型检查,以便在上面的示例中发出警告。我也明白实现类似结果的一种方法是在dummyItem 之前添加/** @type {pendingItem} */ 以强制类型,但出于教育目的,我想知道如何将类型检查添加到push 之类的函数(或者也许pending 本身的更严格定义)。

还有人可以解释重命名对象属性背后的逻辑是什么吗?如果编译上面的例子,它不会将dummyItem的属性重命名为name,而是将token重命名为a。

【问题讨论】:

    标签: javascript google-closure-compiler


    【解决方案1】:

    要对push 强制进行类型检查,必须在代码中使用正确的类型重新定义它。请注意,使用对象文字表示法,您必须使用@type 而不是@param 来定义类型,因为我们将函数分配给对象的参数,而不是定义普通函数。在这种情况下,它将是以下内容:

    /** @type {function(pendingItem)} */
    pending.push = function(item) {
      Array.prototype.push.call(pending, item);
    };
    

    现在尝试编译以下内容时:

    // Still an intentionally misspelled "toke"
    var dummyItem = {
      name: 'NameHere',
      toke: 'SomeToken' 
    };
    
    // First warning
    pending.push(dummyItem);
    
    // Second warning
    pending[1] = {
      name: 'Second name',
      toke: 'Second Token'
    };
    

    然后两者都会像预期的那样生成类型不匹配警告。

    认为它将来可能对某人有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-15
      • 2021-03-12
      • 2013-08-13
      • 2018-01-10
      • 1970-01-01
      • 1970-01-01
      • 2013-09-16
      • 1970-01-01
      相关资源
      最近更新 更多