Repository: TypeScript
Issue: Detect unreachable code in more scenarios
Labels: Suggestion,Awaiting More Feedback

## Search Terms

logical assignment binary expression dead never truthy falsy

## Suggestion

Raise compiler errors when the left side of an expression using a logical operator (`&&` or `||`) is unrechable.

Also detect unreachable branches of ternary expressions.

## Use Cases

Code that is statically verifiable to be unreahable is almost always a programmer error so TypeScript should detect unreachable code in more scenarios.

## Examples

```typescript
declare const truthy: true
declare const falsy: false;
declare function doSomething(): number

const a = true ? 5 : doSomething(); // error: doSomething is unreachable
const b = truthy ? 5 : doSomething(); // error: doSomething is unreachable

const c = false ? doSomething() : 5; // error: doSomething is unreachable
const d = falsy ? doSomething() : 5; // error: doSomething is unreachable

if (!truthy) {
    doSomething(); // error: doSomething is unreachable
}

if (falsy) {
    doSomething(); // error: doSomething is unreachable
}
```

[Playground link.](https://www.staging-typescript.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3hmBXDAFgJ4Bc2eIAUKJLAsulgGZQRqnwtsgDc140OJ1wowGAJap4wJAGUkAWxCFxKAOYAKAJRkUuBQCMQMSpQaZ4UeAF5yuBAH54AVnhkZ8pSvXae8APT+8MYwSDDucorKBKpq8OJo8CJwUGAEUAYQVOZYBjZ2hETwTq4RntGxvgFBIWFlUd5xCUkoKWkZWaY5iPlcaI7SkV4xPlpuLn6BwTCh4YPljfGJySCp6ZnZqBbAvazsxfMNI5pjZM6TNTN1h8OxSy1t652U4kzwGgCEOPjEYwDelHgQJuFVGF2ms3qt3U9xWaw6VAAvqZXu8+kR-oDgR4jpUtODanMcdCmstWqt2htKIigA)

---

It would also be nice to expand unreachable code checks to other expressions that are known to be truthy or falsy eg. object/array literals, NaN eg.

```typescript
declare function doSomething(): number

const a = [1,2,3] || doSomething() // error: doSomething is unreachable
const b = { count: 1 } && doSomething() // error: doSomething is unreachable

if ([1,2,3]) {
    doSomething() // error: doSomething is unreachable
}

if ({ count: 1 }) {
    doSomething() // error: doSomething is unreachable
}
```

[Playground link.](https://www.staging-typescript.org/play?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtX2BwGUcBbEDACy1QHMAKASgC55VlSAjEGAKF7B4AzhnhR4AXngBtAIwAaAEzyAzAF14AH00FiZCtTpN4AehPweMHDFaES5KjVrwsQ+GjhQwlKJwggBYVFOSXgAb3hBNAxWWXgAX3gAMiTdewMnYzMLGCsbNP1HOhc3DxAvHz8A3ixEeHo5JVU1RnDeeA6Ch0MGVuzLa1s9bqcS91RPb19-Xnj+WvqIqNQY+Dj41rD2zrtCnqzzAfzdkeLXccnKmfigA)

---

Finally, detecting unreachable branches of a ternary expression

```typescript
declare const truthy: true
declare const falsy: false;
declare function doSomething(): number

const a = true ? 5 : doSomething(); // error: doSomething is unreachable
const b = truthy ? 5 : doSomething(); // error: doSomething is unreachable

const c = false ? doSomething() : 5; // error: doSomething is unreachable
const d = falsy ? doSomething() : 5; // error: doSomething is unreachable
```

[Playground link](https://www.staging-typescript.org/play?#code/CYUwxgNghgTiAEYD2A7AzgF3hmBXDAFgJ4Bc2eIAUKJLAsulgGZQRqnwtsgDc140OJ1wowGAJap4wJAGUkAWxCFxKAOYAKAJRkUuBQCMQMSpQaZ4UeAF5yuBAH54AVnhkZ8pSvXae8APT+8MYwSDDucorKBKpq8OJo8CJwUGAEUAYQVOZYBjZ2hETwTq4RntGxvgFBIWFlUd5xCUkoKWkZWaY5iPlcaI7SkV4xPlpuLn6BwTCh4YPljfGJySCp6ZnZqBbAvazsxfMNI5pjZM6TNTN1h8OxSy1t61lAA)

## Checklist

My suggestion meets these guidelines:

* [ ] This wouldn't be a breaking change in existing TypeScript/JavaScript code
* [x] This wouldn't change the runtime behavior of existing JavaScript code
* [x] This could be implemented without emitting different JS based on the types of the expressions
* [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).

> This wouldn't be a breaking change in existing TypeScript/JavaScript code

There would be new type errors. The extra safety could be opted into by extending the `allowUnreachableCode` flag or creating a new flag.