I have the following higher order function for wrapping contructors:
/**
* 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);
}
So if I have a class MyClass
, I can do the following:
exports.MyClass = MyClass;
exports.myClass = constructorWrapper(MyClass);
Now the class can be instantiated in the following 2 ways after importing:
const instance1 = new MyClass(param1, param2);
const instance2 = myClass(param1, param2);
In vscode, instance1
will have intellisense support but instance2
won't. How do I document the function/export so that the objects created using the wrapper are recognised as instances of the class?
You could make IntelliSense available by forcing the type of myClass
:
/** @type {function(T1, T2): MyClass} */
exports.myClass = constructorWrapper(MyClass);
If you wish to annotate constructorWrapper
itself, however, that's not possible as of VSCode 1.11.1 (with TypeScript 2.2). While 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);
}
and the inferred type is indeed correct:
Somehow the two "T" becomes disconnected, making myClass = constructorWrapper(MyClass)
to adopt the type signature (...arg0: any[]) => T
. What T
? Well we don't know, treat it as any
and no IntelliSense then.
VSCode's JSDoc-based IntelliSense is based on TypeScript, and I think this is a bug in TypeScript's handling of @template
as of 2.2.
If you are not constrained to ES6-only-development, I recommend you rewrite it entirely in TypeScript instead. Then you'll get the expected IntelliSense, plus type safety and many other benefits.
Note that since TypeScript 2.2 does not support variadic generics yet the arguments can't be perfectly forwarded, thus the input to the myClass
cannot be type-checked. That means you still need to manually annotate the type of myClass
to get perfect information.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With