如何通过JSDoc传递泛型类型参数



在放弃之前,我想在这里试一试。

我有一个定义文件,打字如下:

/**
* My json decode function, in reality very different
* implementation (class like) but it works as an example
*/
function decodeJSON<T = unknown>(str: string): T;

如果我想在TypeScript中使用这个泛型,我会做如下操作以下

const value = decodeJSON<number[]>("[1,2,3]"); // return type will be number[]

然而,在我的实际代码中,我不能使用TypeScript,只是它是用于开发目的的打字,而且我似乎找不到一种方法来告诉我的编辑器我传递给泛型参数的类型是什么,以便我获得正确的类型信息。

我已经尝试使用JSDoc来指定泛型的参数,这可能与TypeScript可以的方式相同

// I was expecting JSDoc to understand something like this, but it doesn't
/** @type {decodeJSON<number[]>} */
const value = decodeJSON("[1,2,3]"); // Type inference will be unknown

但它不起作用。我真的不在乎运行时会有什么结果,我已经实现了健全性检查。我只想让我的编辑器给我关于通用函数结果的类型提示,让我的工作(这个函数在我的应用程序中有一些重要的用途(更容易

我的编辑器是WebStorm,以备不时之需,但这似乎是JSDoc 的一个普遍限制

显然这不是JSDoc可以做的事情,尽管对它的需求有点像真正的

https://github.com/microsoft/TypeScript/issues/27387

您可以使用Jsdoc传递泛型类型,比如:

const value = decodeJSON(/** @type {number[]} */("[1,2,3]"))

如果有人来这里搜索如何使用JsDoc键入ts Generic<T>,我的2美分;

这是

function identity<T>(arg: T): T {
return arg;
}

可以实现为:

/**
* @template T
* @param {T} arg
* @return {T}
*/
function identity(arg) {
return arg;
}

然后:

identity({value: 42}).
^ suggests value: number
/** 
* @type {string} str
* @returns {number[]} // This infers the type to be returned.
*/
function decodeJSON(str) {
// ... your logic
};

考虑问题

const value = decodeJSON<number[]>("[1,2,3]"); // return type will be number[]

我在Github中为jsDoc 找到了更实用的东西

/** @type {ReturnType<typeof decodeJSON<number[]>>} */
const value = decodeJSON("[1,2,3]");

我找到了这个问题的有效解决方案,但它很难看。实际上,您与最初的解决方案非常接近。

从本质上讲,您可以通过类型转换将泛型函数转换为更窄的自身版本。这是代码:

/**
* @template {unknown} T
* @param {string} jsonStr
* @return {T}
*/
function decodeJson(jsonStr) {
return JSON.parse(jsonStr)
}
// narrow the generic via a type cast
let arr = /** @type {typeof decodeJson<number[]>} */ (decodeJson)("[1, 2, 3]")
console.log(arr) // arr should be typeof "number[]" now

这里有一个打字游戏场的链接。

尽管上面的解决方案有效,但实际上可能更好的想法是在从函数返回后直接投射值,如下所示:

let arr = /** @type {number[]} */ (decodeJson("[1, 2, 3]"))

它要简洁得多。

最新更新