Repository: TypeScript
Issue: Support inferring `never` as the return type in JavaScript when overriding a class method that returns `never`
Labels: Suggestion,Awaiting More Feedback,Has Repro

# Suggestion

<!--
  Please fill in each section completely. Thank you!
-->

## 🔍 Search Terms

<!--
  💡 Did you know? TypeScript has over 2,000 open suggestions!
  🔎 Please search thoroughly before logging new feature requests as most common ideas already have a proposal in progress.
  The "Common Feature Requests" section of the FAQ lists many popular requests: https://github.com/Microsoft/TypeScript/wiki/FAQ#common-feature-requests

  Replace the text below:
-->

- JavaScript return never
- JavaScript method return never
- JavaScript override method return never
- JavaScript abstract method return never

## ✅ Viability Checklist

<!--
   Suggestions that don't meet all these criteria are very, very unlikely to be accepted.
   We always recommend reviewing the TypeScript design goals before investing time writing
   a proposal for ideas outside the scope of the project.
-->
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, new syntax sugar for JS, etc.)
* [x] This feature would agree with the rest of [TypeScript's Design Goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals).


## ⭐ Suggestion

<!-- A summary of what you'd like to see added or changed -->

When implementing an abstract method with a signature that returns `never`, the concrete implementation should have its return type inferred as `never` if the method body contains an explicit `throw` and no `return` statements including the implicit `return`.

## 📃 Motivating Example

<!--
  If you were announcing this feature in a blog post, what's a short explanation that shows
  a developer why this feature improves the language?
-->

[Workbench Repro](https://www.typescriptlang.org/dev/bug-workbench/?noImplicitAny=false&checkJs=true&allowJs=true&target=99&noEmit=true&lib=lib.esnext.d.ts&ts=lib.esnext.d.ts#code/PTAEAEEMBtoewO4CkDOBYAUCCBjAFgKY4DWqm24AdnAKIC2AlgC7lhVwCSdADtAzswCClAJ4AuUADMYKAqwhNIAJwDmBJhJoBlAHIEAHiyxs6cACYBXaAU26DRinwBGtvYczzwkhtcqQ6NqBMcMQElCgAdGYRTOjGoABCkLJmoHCUEnhMTNwoYiAqzHgWThE4cHTAYYWUBABMAGx1VZQ19U3ATEoEBMB0kAyUwChKOMDcyrJKnSFhkXQAVnEG3HBKTKBhFnSgACqzlKAA3pgAkNgRl2c0APJaoAC8oACMAMwANGcXVxgAvh7xLw+ML+QIAGQMBCUURicWwSRSaQyoCyOTyBSKJTKFRabUazWqg3azS6PT6AyGIzGEyUU2AEP0UIiiziDB4aw2Rz2B1AvykSgqoAARBEZqFwhElkKANwAlYc0CDJhQ6Q4AigAAKkwIZn24uOZyYIm4gT1YVlGHOYEuEUw-wwmHl61AkCcKC6kBwGxw0GSKFADKhBst31tlpNBGIAAoAJQSLW0nVmygWr7Wn6nV3upSe73dSDKrQiSiKfQ0JQCpRRs6ncol+wSOBOBZEDYAH1AlG2TiDHYslDMBG8tTMn0tp2VPF9yok2cGKjHpwnBCnBYIglUeVA+bM6WgIlA-eI1AQlAA2gBdM5x0BFkuQMsVtYWzNuj1e7cDWQ0ZT76vjydeDXWcunnRda3SZVDAAfkbZtW1ADsuzoHslHAm1AOnddNwkHc9wPI8T3PK9LRvO9S3LSsXyzd8NhzBhZH-K1QBY1i2IAPWgmtMOA0A51acC6ygphYLSeCPyQ7soXQy4eOVDcVC3PDKH3Q9KGPRBiOvCRagANyhai3xzD9+xWVsdSYiD6xguCWwkzspLQmsMJXID5Jw7cCEgXcVII9SiMvbTOwIfSlAte1PG8XxQXjbVoSWeQER1JFMmyXJ8mAQomGKUpykqQlanxXEiSK0len6QZhlGcY4uABMpmZBKMDZVZnS5QMlF5flBRFelIXilAZUwFqFS5ZMuskAUdl64JxUiKVUwwJ1vV9FB-XqoN7DCMx-Q64NTi8pR90otZ-SeWoEFAFR4CcGBdjwBiIi0dRY0W2t80LYsKKfKshPsR4ggeyII2jGN3iCVysPBuTsMUmN9tOBhJFAKMYceB4niFABVWp9BNL0kwOIVQAAMhJ0A-sMGJjXVDGnmTCJbi0eGTnHZdV2VAHsdx-HlTMJmhvHe0l1DGtuiYCwlEOC6rpuu6gaer6HxOqtgAAKlAG1QDV4AYxfCLLXo79fxEVHIbXcHKaYcGXI52GUBZms63dTYAeyx6cA+ghyOVn6oyt6HzeVQO7YUh2XwnBXDuOn7Im8swowIPWxfUSXDgIfWAWYmg8fM1JxbToIabEU49KhNNWMEL0LBgTyJalouTRL3S4AYMwziNggzbty3IPsG3ZKD+3HZDMBOO4vABUu93Ik9rzPvvR9K39vvDBDtyCHXrCw+Ty0DdOUzc4JhOA81wfQ83EelwLhuZ4iTuV+s63hRxszj+TIUt7XHfM7+TAgA):
<details>

```ts repro
// @allowJs
// @checkJs
// @noEmit
// @noImplicitAny: false
// @target: ESNext
// @module: ESNext
// @lib: ESNext

// @filename: tokens.d.ts
// Based on: https://github.com/engine262/engine262/tree/main/src/parser/tokens.mjs
export enum Token {
	// ...
	EOS = 13,
	// ...
}

// @filename: Lexer.d.ts
// Based on: https://github.com/engine262/engine262/tree/main/src/parser/Lexer.mjs
import { Token } from "./tokens.js";

export interface ParsedToken {
	type: Token;
	// ...
}

export abstract class Lexer {
	// ...
	peek(): ParsedToken;

	// ...
	abstract createSyntaxError(
		context: object | number | undefined,
		template: string,
		templateArgs: readonly unknown[]
	): SyntaxError;
	abstract raiseEarly(
		template: string,
		context?: object | number,
		...templateArgs: readonly unknown[]
	): SyntaxError;
	abstract raise(
	//          ^?
		template: string,
		context?: object | number,
		...templateArgs: readonly unknown[]
	): never;
	abstract unexpected(
		context?: object | number,
		...templateArgs: readonly unknown[]
	): never;
}

// @filename: Parser.js
// Based on: https://github.com/engine262/engine262/tree/main/src/parser/Parser.mjs
import { Lexer } from "./Lexer.js";
import { Token } from "./tokens.js";

export class Parser extends Lexer {
	earlyErrors = new globalThis.Set();

	createSyntaxError(context = this.peek(), template, templateArgs) {
		if (template === "UnexpectedToken" && context.type === Token.EOS) {
			template = "UnexpectedEOS";
		}
		// ...
		return new globalThis.SyntaxError(/* ... */);
	}

	raiseEarly(template, context, ...templateArgs) {
		const e = this.createSyntaxError(context, template, templateArgs);
		this.earlyErrors.add(e);
		return e;
	}

	// Expected return type:	never
	//   Actual return type:	void
	raise(template, context, ...templateArgs) {
	// ^?
		throw this.createSyntaxError(context, template, templateArgs);
	}

	unexpected(context, ...templateArgs) {
		return this.raise(context, "UnexpectedToken", templateArgs);
	}
}
```
</details>

## 💻 Use Cases

<!--
  What do you want to use this for?
  What shortcomings exist with current approaches?
  What workarounds are you using in the meantime?
-->

To get better type inference while working on [engine262](https://github.com/engine262/engine262)’s parser.

## Relevant issues
- <https://github.com/microsoft/TypeScript/issues/32082>