visual-studio-code - 如何使用 vscode 中的 jsdoc 在包装函数中正确获取返回值的推断类型?

标签 visual-studio-code types jsdoc

为了更好地理解,这里有一些代码(经过简化):

发送请求的包装器

  • 它在请求发送和完成时做一些常见的事情。
  • 它返回请求的结果(处理程序)。
async function request (handler) {
  // common stuff
  try {
    const result = await handler()
    return result || true
  }
  catch (err) {
    doSomethingWithError(err)
    return err
  }
  finally {
  // common stuff
  }
}

/**
 * Imagine a simple service / api client
 */
const someApiClient = {
  /**
   * @returns {Promise<string[]>} 3 first letters
   */
  async getSomeData () {
    return ['a', 'b', 'c']
  }
}

/**
 * Just a function or method using the api client, that has types declared
 */
async function fetchMeSomeDataHandler () {
  return someApiClient.getSomeData()
}

const result = await request(() => fetchMeSomeDataHandler())

预计

在这里,我希望 vscode/jsdoc 推断“结果”的类型是字符串[],甚至给我来自 api 客户端的描述(“3 个首字母”)。

但它不是,它会在最后给出一个类型any

我们在 vscode 中得到了什么

如果我们跟踪 vscode 拾取的类型,我们可以看到它正在“一点一点地丢失类型”,直到什么都没有为止。

  1. 为 api 客户端获取的完整类型描述。

Full type description in the api client

  1. 类型在处理程序定义中已知,但我们丢失了客户端值描述(3 个首字母)。

The type is known in the handler definition but we lost the client value description

  1. 我们完全丢失了最终结果的类型信息

We lost the type information completely

最佳答案

VS Code 会尝试根据函数参数的用法来推断函数参数的类型。一个简单的例子是:

function foo(a) {
    return a.b;
}

foo({ b: 3 })

这导致 foo 具有签名 function foo(a: any): any。您的代码是此限制的一个更复杂的示例。

修复方法是在request 上显式注释参数类型:

/**
 * @template T
 * @param {() => Promise<T>} handler 
 * @return {Promise<T>}
 */
async function request(handler) {
   ...
}

在这种特定情况下,我们还需要显式的 @returns 因为 catch block 不返回类型 T 的值(它返回一个 any 因为错误是未类型化的)。

如果编写了request,您可以省略@returns:

/**
 * @template T
 * @param {() => Promise<T>} handler 
 */
async function request(handler) {
    // common stuff
    const result = await handler()
    return result
}

因为 VS Code 可以推断函数的返回类型(但请记住,显式类型在许多情况下很有用,尤其是对于可能返回多种不同类型的函数)

添加显式类型后,result 应该具有正确的类型:

enter image description here

关于visual-studio-code - 如何使用 vscode 中的 jsdoc 在包装函数中正确获取返回值的推断类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63615171/

相关文章:

javascript - 描述使用 Object.defineProperty 定义的属性

Javascript + JsDoc : How to document new ES6 datatypes like map?

右键单击 VSCode 时,Flutter::My Refactor 按钮不会出现

python - 在 VSCode 中设置 pylint/pycodestyle 的全局路径

python - 在使用 Python 的 vscode 中,ctrl+F5 总是要求输入 "select environment"

c# - 为什么不能从泛型约束中隐式推断出 `this` 的类型转换?

visual-studio-code - RStudio 中是否有与 VS Code 中的 Ctrl + D 命令等效的快捷方式?

python - 动态创建子类的类型注解

python - 如何对字符串进行数学运算?

google-apps-script - 用于在 Google 表格自动完成下拉列表中显示可选参数的 JSDoc