Add an entry in `compilerOptions` to forbid throwing anything except Error and it's derivates.
See original GitHub issueSuggestion
🔍 Search Terms
- catch
- catch clause
- unknown type in catch clause
- force Error in catch
✅ Viability Checklist
My suggestion meets these guidelines:
- [✅] This wouldn’t be a breaking change in existing TypeScript/JavaScript code
This being fully compatible with default Javascript behavior wouldn’t override any Javascript native behavior. Moreover, making it an option defaulting to
false
would not break any existing TypeScript code.
- [✅] This wouldn’t change the runtime behavior of existing JavaScript code
- [✅] This could be implemented without emitting different JS based on the types of the expressions
- [✅] This isn’t a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [✅] This feature would agree with the rest of TypeScript’s Design Goals.
⭐ Suggestion
Recently TypeScript moved forward regarding try/catch
statements to make the parameter of catch
being of type unknown
which is a great start. However, it is bad practice to throw anything that does not inherit from Error, especially throwing literals. My suggestions has two different parts.
- 1 - Add a
compilerOptions
entry refusing any literal throw or throw anything that does not inherit from Error. - 2 - With this option, always consider that the parameter from
catch
will always and can only be an instance of Error.
To my knowledge, there is no native Javascript code that throws literal. I may be wrong but I think Javascript exclusively throws Errors natively and nothing else. This would make it fully compatible with JavaScript but will reduce code verbosity when using try/catch
statements, avoiding unnecessary type checks. It would also enforce a good practice overall.
📃 Motivating Example
Throwing literals is often considered bad practice. Throwing exclusively Errors is widely regarded as the right practice in the Javascript community as demonstrated by the implementation of this rule at Beta stage of ESlint: https://eslint.org/docs/rules/no-throw-literal (0.15).
While the current state of TypeScript regarding catch
clauses allows throwing literals because Javascript does, it also forces people following best practices to engage into extra unnecessary type validation checks. Since the idea is that any Javascript code is valid in TypeScript, it should be an option to make checking more strict instead of being enforced by default.
💻 Use Cases
There are an infinite amount of use cases as it touches the catch
clause behavior. Ultimately this aims to improves readability of TypeScript code, avoid unnecessary type checking and unnecessary verbosity.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:1
- Comments:7 (2 by maintainers)
Top GitHub Comments
I think that sounds more suitable for a linter than the type-system.
This is true, however, third party code throwing literals is more a problem between the user of the library and the developer of the library. Crudely put, I don’t think TypeScript should take dubious libraries into account when implementing new options that are turned off by default.