Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Promise<never> not considered in reachability analysis?

Assume we have this function:

function returnNever(): never {
    throw new Error();
}

When creating an IIFE, the code that comes after it becomes marked as unreachable:

(async () => {
    let b: string;
    let a0 = returnNever();
    b = ""; // Unreachable
    b.toUpperCase(); // Unreachable
})();

This works as expected. Note that a0 is inferred to be of type never.

However, if returnNever() returns a Promise<never> and gets awaited, the behaviour is different:

(async () => {
    let b: string;
    let a1 = await Promise.reject(); // returns Promise<never>
    b = ""; // Not unreachable?
    b.toUpperCase(); // Not unreachable?
})();

In this case, a1 is also inferred to be of type never. But the code afterwards is not marked as unreachable. Why?

Background: I recently stumbled upon some logError function that looked like in the following code. It was used inside a catch block. This way, I discovered, that not reachability analysis, but also definite assignment analysis is influenced by that:

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
})();

If logError is made synchronous (by removing all awaits and asyncs that have to do with logError), there is no error. Also, if let b: string is changed to let b: string | undefined, the undefined is not getting removed after the try-catch block.

It seems that there is a reason to not consider awaits of Promise<never>-returning functions in any aspect of the control flow analysis. It might also be a bug, but I rather think that I am missing some detail here.

like image 333
nikeee Avatar asked Sep 05 '25 02:09

nikeee


1 Answers

It might also be a bug, but I rather think that I am missing some detail here.

It is indeed a bug, and the GitHub issue (reported by the author of this question) regarding it can be found here. As of January 2025, the issue is still unresolved.

like image 182
kaya3 Avatar answered Sep 07 '25 18:09

kaya3



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!