如何在vscode中使用jsdoc在包装函数中正确获取返回值的推断类型? [英] How to properly get inferred types of returned values in a wrapper function with jsdoc in vscode?

查看:142
本文介绍了如何在vscode中使用jsdoc在包装函数中正确获取返回值的推断类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里有一些代码(简体)可以更好地理解:

Here is some code (simplified) to understand better:

  • 发送请求和完成请求时,它会做一些常见的事情.
  • 它返回请求的结果(处理程序).
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能够推断出结果"类型是结果".是string [],甚至还给了我来自api客户端的描述("3个首字母").

Expected

Here, I would expect vscode / jsdoc to infer that the type of "result" is string[] and even give me the description from the api client ("3 first letters").

但不是,它将在末尾给出 any 的类型.

But it isn't, it will give a type of any at the end.

如果我们遵循vscode挑选的类型,我们可以看到它一点一点地丢失了类型".直到剩下一无所有.

If we follow the types picked up by vscode, we can see it's "losing the types little by little" until there is nothing left.

  1. 为api客户端选择了完整的类型说明.

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

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

推荐答案

VS代码确实会尝试根据其用法来推断函数参数的类型.一个简单的例子是:

VS Code does try to infer the types of function parameters based on their usage. A simple example of this is:

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

foo({ b: 3 })

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

Which results in foo having the signature function foo(a: any): any. Your code is a more complex example of this limitation.

解决方法是在 request 上显式注释参数类型:

The fix is to explicitly annotate the parameter type on request:

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

在这种特定情况下,我们还需要显式的 @returns ,因为catch块不会返回类型为 T 的值(它返回的是 any ,因为未输入错误).

In this specific case, we also need the explicit @returns since the catch block does not return a value of type T (it returns an any since the error is untyped).

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

You can omit the @returns if request were written:

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

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

Because VS Code can infer the return types of functions (but keep in mind that explicit types are useful in many cases, especially for functions that may return multiple different types)

添加明确的类型后,结果应具有正确的类型:

After adding the explicit typings, result should have the correct type:

这篇关于如何在vscode中使用jsdoc在包装函数中正确获取返回值的推断类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆