这是一些代码(简化的)以更好地理解:
发送请求的包装器
- 当请求发送和完成时,它会执行一些常见的操作。
- 它返回请求的结果(处理程序)。
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())
Expected
在这里,我希望 vscode / jsdoc 推断“结果”的类型是 string[],甚至给我 api 客户端的描述(“3 个第一个字母”)。
但事实并非如此,它会给出一种类型any
在最后。
我们在 vscode 中得到了什么
如果我们跟踪 vscode 获取的类型,我们可以看到它“一点一点地丢失类型”,直到什么都没有剩下。
- 为 api 客户端选取的完整类型描述。
- 该类型在处理程序定义中是已知的,但我们丢失了客户端值描述(前 3 个字母)。
- 我们完全丢失了最终结果的类型信息
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 块不返回 type 的值T
(它返回一个any
因为错误是未键入的)。
您可以省略@returns
if request
被写:
/**
* @template T
* @param {() => Promise<T>} handler
*/
async function request(handler) {
// common stuff
const result = await handler()
return result
}
因为 VS Code 可以推断函数的返回类型(但请记住,显式类型在许多情况下很有用,特别是对于可能返回多种不同类型的函数)
添加显式类型后,result
应该有正确的类型:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)