我有以下用于包装构造函数的高阶函数:
/**
* Wrapper for calling constructor with given parameters
*
* @param {Class} Cls
* @returns {function} Wrapper on constructor which creates an instance of given Class
*/
function constructorWrapper(Cls) {
return (...args) => new Cls(...args);
}
所以如果我有一个类 MyClass
,我可以执行以下操作:
exports.MyClass = MyClass;
exports.myClass = constructorWrapper(MyClass);
现在该类在导入后可以通过以下两种方式实例化:
const instance1 = new MyClass(param1, param2);
const instance2 = myClass(param1, param2);
在 vscode 中,instance1
将具有智能感知支持,但 instance2
不会。我如何记录函数/导出以便将使用包装器创建的对象识别为类的实例?
最佳答案
您可以通过强制 myClass
的类型使 IntelliSense 可用:
/** @type {function(T1, T2): MyClass} */
exports.myClass = constructorWrapper(MyClass);
但是,如果您希望注释 constructorWrapper
本身,从 VSCode 1.11.1(使用 TypeScript 2.2)开始,这是不可能的。同时JSDoc supports generics :
/**
* Wrapper for calling constructor with given parameters
*
* @param {function(new:T, ...*)} Cls The class constructor.
* @returns {function(...*): T} Wrapper of the class constructor
* @template T
*/
function constructorWrapper(Cls) {
return (...args) => new Cls(...args);
}
并且推断的类型确实是正确的:
不知何故,两个“T”断开连接,使 myClass = constructorWrapper(MyClass)
采用类型签名 (...arg0: any[]) => T
。什么 T
?好吧,我们不知道,将其视为 any
并且没有 IntelliSense。
VSCode 基于 JSDoc 的 IntelliSense 基于 TypeScript,并且 I think this is a bug in TypeScript's handling of @template
从 2.2 开始。
如果您不局限于纯 ES6 开发,我建议您完全用 TypeScript 重写它。然后您将获得预期的 IntelliSense,以及类型安全和许多其他好处。
注意自 TypeScript 2.2 does not support variadic generics yet无法完美转发参数,因此无法对 myClass
的输入进行类型检查。这意味着您仍然需要手动注释 myClass
的类型以获得完美的信息。
关于javascript - 如何记录javascript高阶函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43336416/