Skip to content

In finally block, local variable is incorrectly typed as never with return in try block. #28153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
OpenSourceAries opened this issue Oct 26, 2018 · 2 comments
Assignees
Labels
Bug A bug in TypeScript Domain: Control Flow The issue relates to control flow analysis

Comments

@OpenSourceAries
Copy link

TypeScript Version: 3.1.3

Search Terms: try finally block

Code

async function test(): Promise<string> {
    let browser: puppeteer.Browser | undefined = undefined;
    let page: puppeteer.Page | undefined = undefined;
    try {
        browser = await test1();
        page = await test2(browser);
        return await page.content();;
    } finally {
        if (page) {
            await page.close();
        }

        if (browser) {
            await browser.close();
        }
    }
}

async function test1(): Promise<puppeteer.Browser> {
    return await puppeteer.launch();
}

async function test2(browser: puppeteer.Browser): Promise<puppeteer.Page> {
    return await browser.newPage();
}

Expected behavior:
page and browser can be of type puppeteer.Page and puppeteer.Browser

Actual behavior:
compile error message:
error TS2339: Property 'close' does not exist on type 'never'.

Related Issues:
#11665(The different is current issue's code contains a return in try block)

@weswigham weswigham added Bug A bug in TypeScript Domain: Control Flow The issue relates to control flow analysis labels Oct 26, 2018
@woutervh-
Copy link

woutervh- commented Nov 1, 2018

The same happens in the catch block. Here is my minimal reproduction of the error I run into:

class Foo {
    abortController: AbortController | undefined = undefined;

    async operation() {
        if (this.abortController !== undefined) {
            this.abortController.abort();
            this.abortController = undefined;
        }
        try {
            this.abortController = new AbortController();
            // rest of code...
        } catch (error) {
            if (this.abortController !== undefined) {
                this.abortController.abort(); // Property 'abort' does not exist on type 'never'
            }
        }
    }
}

Playground link

@rulatir
Copy link

rulatir commented Apr 3, 2021

Still experiencing this for the simplest of cases as of 4.2.3:

import {performance} from "perf_hooks";

let riskyStuffTook = 0;

function foo() {
    
    let start : number;
    try {
        start = performance.now(); // <- ASSIGNING HERE!!!
        doRiskyStuff();
    }
    finally {
        riskyStuffTook += performance.now() - start; // TS2454: Variable 'start' is used before being assigned.
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Domain: Control Flow The issue relates to control flow analysis
Projects
None yet
Development

No branches or pull requests

5 participants