microsoft / microsoft/TypeScript

Explicit `never` return type in `catch` block & condition in `finally` marks the whole `finally` block as unreachable

Open
#63,004 2 comments 1 reaction 0 assignees View on GitHub
Bug Domain: check: Control Flow
Dominant language
Go
Stars
111k
Forks
14.3k
PR merge metrics
PR metrics pending

Description

### 🔎 Search Terms

finally, unreachable, condition, never

### 🕗 Version & Regression Information

- This builds fine in 3.2,
- produces a type error regarding the return type in 3.3 through 3.6,
- and starting 3.7, including the latest native preview, it produces the unreachable code error

### ⏯ Playground Link

https://www.typescriptlang.org/play/?noImplicitAny=false&ts=5.9.3#code/MYewdgzgLgBATgUwA4jlAXDAFAzBDMATwEoYBeAPhjAQDcE5zsFjMb7HKYBvAKBhhQAFnBAB3GAgDcvAL4zeoSLABmIEEzwRCYYNlYwACqIC2ASwgIAPGACuJgEYMqXPgKhxCPfgPgIotnBgMADMMgKyMMB4UMBCzKRuvogoaDjE4TCRKmZgeAA2+V5JAmYq2B62LN6+vkoQIPkIAHT5IADmWABEQghCXRk+ET6yclJAA

### 💻 Code

```ts
function report(e): never {
throw e;
};

const foo = async (): Promise => {
try {
return 3;
} catch (e) {
report(e);
} finally {
if (true) {
console.log("heh");
}
}
};
```

### 🙁 Actual behavior

```
test.ts:11:5 - error TS7027: Unreachable code detected.

11 if (true) {
~~~~~~~~~~~
12 console.log("heh");
~~~~~~~~~~~~~~~~~~~~~~~~~
13 }
~~~~~

test.ts:12:7 - error TS7027: Unreachable code detected.

12 console.log("heh");
~~~~~~~~~~~~~~~~~~~
```

### 🙂 Expected behavior

Builds fine.

### Additional information about the issue

This error vanishes if I do any of the following:

- Remove the explicit `never` return type of `reportError` (although that resurfaces the return type error)
- Remove the call to `reportError` entirely, or the whole `catch` block
- Remove the `if` condition from the `finally` block, but leave in the `console.log` call

I found a similar issue #61259, but it does not include a `catch` block, which is integral to the issue here - although the issues might still be related. Similarly to that issue, the `finally` block also becomes reachable when adding another `return` to the `catch` block, but it is itself unreachable.

Contributor guide

Open the contributing guide

Research direction

Reproduce the diagnostic in the linked TypeScript Playground and compare the behavior across the versions described, especially 3.6 and 3.7. Read related issue #61259 and trace the control-flow handling for the catch and finally blocks; done means the example builds without TS7027 while retaining the explicit never return type.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.