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 –