2

我已经包裹contructors以下高阶函数:如何记录JavaScript高阶函数?

/** 
* 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); 

现在的类可以在下面的实例2种方式导入后:

const instance1 = new MyClass(param1, param2); 
const instance2 = myClass(param1, param2); 

在vscode中,instance1将具有智能感应支持,但instance2不会。如何记录函数/导出,以便使用包装器创建的对象被识别为类的实例?

+1

JavaScript有时并不真正记录在'vscode'上,使用Typescript代替:( – Chris

回答

1

你可以做智能感知可通过强制的myClass类型:

/** @type {function(T1, T2): MyClass} */ 
exports.myClass = constructorWrapper(MyClass); 

如果你要注释constructorWrapper本身,但是,这是不可能的,因为VSCode 1.11.1(带打字稿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); 
} 

,并推断出的类型确实是正确的:

<code>function constructorWrapper<T>(Cls: new (...arg1: any[]) => T): (...arg0: any[]) => T</code>

不知何故,两个 “T” 断开,使myClass = constructorWrapper(MyClass)采用类型签名(...arg0: any[]) => T。什么T?那么我们不知道,把它当作any,然后不用IntelliSense。

<code>myClass: (...arg0: any[]) => T</code>

VSCode的基于JSDoc,智能感知是基于打字稿,并I think this is a bug in TypeScript's handling of @template为2.2。

如果您不受限于ES6-only-development,我建议您完全用TypeScript重写它。然后,您将获得预期的IntelliSense,以及类型安全性和许多其他好处。

请注意,由于TypeScript 2.2 does not support variadic generics yet参数不能完美转发,因此无法对类型检查myClass的输入。这意味着您仍然需要手动注释myClass的类型以获取完美信息。

+0

感谢您花时间回答这个问题,但手动注释'myClass'类型在vscode中不起作用。这是一个错误/丢失的功能,没有更好的解决方案,我仍然喜欢答案 –

+0

@SuhasK在VSCode 1.11.1手动添加'@ type'适用于TypeScript 2.2.2。你的'import'语句? – kennytm

+0

事实上,如果类定义存在于导出的同一个文件中,它的工作原理就是如果它被导入然后导出(就像我的情况那样),即使使用手动类型,intellisense也不起作用注释 https://ibb.co/m5qW0k –