如何记录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);

现在,在导入后,可以通过以下两种方式实例化类:

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

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

最佳答案 您可以通过强制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?好吧,我们不知道,然后把它视为任何智能感知.

VSCode基于JSDoc的IntelliSense基于TypeScript,而I think this is a bug in TypeScript’s handling of @template则基于2.2.

如果您不仅限于ES6开发,我建议您完全使用TypeScript重写它.然后,您将获得预期的智能感知,以及类型安全和许多其他好处.

请注意,从TypeScript 2.2 does not support variadic generics yet开始,参数无法完美转发,因此无法对myClass的输入进行类型检查.这意味着你仍然需要手动注释myClass的类型以获得完美的信息.

点赞