如何使用Google闭包编译器引用复杂的函数类型而不是构造函数的实例?
externs.js - CoolLibrary.matchSomething的外播
/** @externs */
/** @const */
const CoolLibrary = {};
/**
* @param {!Object} object The object to inspect.
* @param {!Object} source The object of property values to match.
* @param {!function(!Object): !Object} customizer The function to customize
* comparisons.
* @return {boolean} Returns `true` if `object` is a match, else `false`.
* @constructor
*/
CoolLibrary.matchSomething = function(object, source, customizer) {};
/**
* @param {string} src
* @return {!Object}
*/
function require(src) {}
foo.js - 应用程序代码
goog.module('foo');
const isMatchWith = /** @type {!CoolLibrary.matchSomething} */ (require('coollibrary.matchsomething'));
const foo = isMatchWith({}, {}, (val) => {});
我这样调用它:
java -jar closure-compiler-v20161201.jar --js=foo.js --externs=externs.js --new_type_inf
的可运行版本
错误:
foo.js:3: WARNING - Bad type annotation. Unknown type Lodash.isMatchWith
const isMatchWith = /** @type {!Lodash.isMatchWith} */ (require('lodash.ismatchwith'));
^
0 error(s), 1 warning(s), 72.7% typed
如果我使用@typedef
但它丢失了大部分信息,它就有效。有没有比使用类似下面的typedef更好的方法来添加类型信息?
/** @typedef {function(!Object, !Object, function(!Object):!Object):boolean} */
CoolLibrary.matchSomething;
答案 0 :(得分:2)
函数定义不是类型名称。如果在多个位置导入函数,可以使用typedef来防止重新输入此数据。但是,如果您只在一个地方导入信息,那么typedef就会过度。
对于单个导入,您只需在require
调用的类型中复制功能注释。
const isMatchWith =
/** @type {function(!Object, !Object, function(!Object):!Object):boolean} */
(require('lodash.ismatchwith'));
编译器在使用模块捆绑时会为您处理这些情况,但这需要所有源文件与编译器兼容并作为编译的一部分提供。目前,外部库无法实现。