在放弃之前我想在这里尝试一下。
我有一个定义文件,其类型如下:
/**
* 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 可以做的事情,尽管确实有这样的需求
您可以使用 Jsdoc 传递泛型类型,如下所示:
const value = decodeJSON(/** @type {number[]} */("[1,2,3]"))
如果有人来这里搜索如何使用 JsDoc 输入 ts Generic
<T>
,我的 2 美分;
这个ts
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]"))
更加简洁。
const value = /** @type {decodeJSON<number[]>} */ (decodeJSON)("[1,2,3]"); // Type inference will be unknown
注意周围多余的括号decodeJSON
。