Description
Bug Report
I'm not exactly sure if this is a bug or not - CFA rules are not well-documented. I find the present behavior to be quite annoying though
🔎 Search Terms
narrowing, control flow analysis, nullable, optional chaining
🕗 Version & Regression Information
// purposefully use `@types/*` here because otherwise I had problems with ATA
import '@types/vscode-webview'
const vscode: ReturnType<typeof acquireVsCodeApi> | undefined = acquireVsCodeApi?.()
// ^? WebviewApi<unknown> | undefined
vscode
// ^? WebviewApi<unknown>
// attempt to wrap in an IIFE
const vscode2: ReturnType<typeof acquireVsCodeApi> | undefined = (() => acquireVsCodeApi?.())();
// ^? WebviewApi<unknown> | undefined
// no change though
vscode2
// ^? WebviewApi<unknown>
const vscode3: ReturnType<typeof acquireVsCodeApi> | undefined = acquireVsCodeApi ? acquireVsCodeApi() : undefined;
// ^? WebviewApi<unknown> | undefined
// finally 🎉
vscode3
// ^? WebviewApi<unknown> | undefined
🙁 Actual behavior
Referencing a variable with the declared type that originates in an expression using optional chaining doesn't include | undefined
in its type.
Note that acquireVsCodeApi
is always defined according to the types.
🙂 Expected behavior
Even though acquireVsCodeApi
is always defined I would expect my explicit declaration on the assigned variable to win for the purpose of CFA.
I have an app that is running as a standalone but it's also bundled as a VS Code extension. It's a hussle to include the VS Code types conditionally and it's much easier for us to just add those defs globally and refine this stuff at runtime when needed.