Skip to content

Control flow analysis overriding an explicit type declaration when the type flows from optional chaining #50444

Closed as not planned
@Andarist

Description

@Andarist

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Not a DefectThis behavior is one of several equally-correct options

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions