typescript - 为什么是承诺在可达性分析中没有考虑?
问题描述
假设我们有这个函数:
function returnNever(): never {
throw new Error();
}
创建 IIFE 时,它之后的代码被标记为不可访问:
(async () => {
let b: string;
let a0 = returnNever();
b = ""; // Unreachable
b.toUpperCase(); // Unreachable
})();
这按预期工作。请注意,a0
推断为 type never
。
但是,如果returnNever()
返回 aPromise<never>
并等待,则行为不同:
(async () => {
let b: string;
let a1 = await Promise.reject(); // returns Promise<never>
b = ""; // Not unreachable?
b.toUpperCase(); // Not unreachable?
})();
在这种情况下,a1
也被推断为 type never
。但是之后的代码没有被标记为不可访问。为什么?
背景:我最近偶然发现了一些logError
类似于以下代码的函数。它在一个catch
块内使用。这样,我发现,不是可达性分析,而是明确的分配分析都会受到以下因素的影响:
declare function fetchB(): Promise<string>;
async function logError(err: any): Promise<never> {
await fetch("/foo/...");
throw new Error(err);
}
(async () => {
let b: string;
try {
b = await fetchB(); // Promise<string>
} catch (err) {
await logError(err); // awaiting Promise<never>
}
b.toUpperCase(); // Error: "b" is used before assignment
})();
如果logError
是同步的(通过删除与 s 相关的所有await
s 和async
s logError
),则没有错误。此外,如果let b: string
更改为let b: string | undefined
,undefined
则在 try-catch 块之后不会被删除。
似乎有理由在控制流分析的任何方面不考虑返回函数的await
s 。Promise<never>
这也可能是一个错误,但我宁愿认为我在这里遗漏了一些细节。
解决方案
推荐阅读
- haskell - Haskell`hlint`,如何添加错误缩进、尾随空格等提示?
- jwt - 如何从 go-swagger 中的 API 处理函数访问 JWT 声明?
- android - Android API 28 模拟器点击问题上的 Espresso 测试
- javascript - 饼图中的 D3 标签被切断
- javascript - 在获取结构以获取结果期间出现问题 [VueJs]
- c# - 在 ASP.Net MVC 中删除记录的安全方法
- reactjs - 将 react-google-maps 方法与 recompose 一起使用
- javascript - 我们可以对 promise 使用 await 和相同的函数吗?
- mysql - mysqlimport:错误:1083,字段分隔符参数不是预期的
- excel - 为 Excel 中的每个唯一名称分配唯一 ID