Incorrect use-before-declaration error in async IIFE initializer
#50,123 创建于 2022年8月1日
仓库指标
- Star
- (48,455 star)
- PR 合并指标
- (平均合并 6天 17小时) (30 天内合并 9 个 PR)
描述
Bug Report
🔎 Search Terms
- dead zone
- await tdz
- use before declaration await
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about await
⏯ Playground Link
Playground link with relevant code
💻 Code
const promise = (async () => {
await null
promise
})()
useEffect(() => {
const request = (async () => {
try {
const response = await premiumApi.announcements(client)
// @ts-expect-error TypeScript bug, assumes "request" is still in dead zone after await
if (pendingRequest.current === request || pendingRequest.current === undefined) {
pendingRequest.current = undefined
setApiResponse(response)
}
} catch {
pendingRequest.current = undefined
}
})()
pendingRequest.current = request
return () => {
pendingRequest.current = undefined
}
}, [client])
🙁 Actual behavior
- "Block-scoped variable 'promise' used before its declaration."
- "Variable 'promise' is used before being assigned."
🙂 Expected behavior
- No errors related to the
promisevariable.
This is not about the "'await' has no effect on the type of this expression" warning, this is a feature and is expected despite me disagreeing with it.
The first await to be reached in an async function is the point where the function stops being synchronous and yields a Promise for its result. This means that, immediately after the await, the const promise is no longer in TDZ and is well-defined: it is the not-yet-resolved Promise that was produced by the IIFE's invocation. Now, awaiting the promise would be a deadlock, as the promise would now be waiting for itself to resolve before being able to resolve, but the Promise instance itself is still useful for some purposes like === checks.