microsoft / microsoft/TypeScript
The `strict` option is confusing since TypeScript 6
- Dominant language
- Go
- Stars
- 111k
- Forks
- 14.3k
- PR merge metrics
- PR metrics pending
Description
### Acknowledgement
- [x] I acknowledge that issues using this template may be closed without further explanation at the maintainer's discretion.
### Comment
In TypeScript 5 and below, `strict` was disabled by default. The `strict` option could be explained as a preset that enables certain options related stricter type checking, that weren’t enabled by default. I think for many users this option was analogous to _strict null checks and probably some other stuff_.
My take is practically akin to the above, but with a bit more nuance. When `strict` was introduced in [TypeScript 2.3](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html), this was a preset that includes the 4 options `strictNullChecks`, `noImplicitAny`, `noImplicitThis`, and `alwaysStrict`. This strict mode came with the caveat that TypeScript might cause build failures, which many users have considered breaking changes in minor versions over the past years. In TypeScript 5, strict mode enabled 9 options.
The way I see it, strictness options follow several stages:
1. The option does not exist.
2. The option is introduced, but disabled by default.
3. The option is enabled if `strict` is enabled.
4. The option is enabled by default.
Maybe some stages are skipped. Maybe some stages are never reached.
---
In TypeScript 6, `strict` was changed to `true` by default. This was celebrated, because many people nowadays believe that these strict options are good. (And I agree!)
In my opinion however, this completely changed its meaning. This merges the stages 3 and 4. `strict` is no longer a preset to enable more strict options. Instead, it is now a preset you can use to enable 9 looser type checking options. You enable _loose_ mode by setting an option named _strict_ to _false_. You and I are aware how this came to be, but this is very weird to explain to new users. Understanding this option, requires understanding its history. Meanwhile, the explanations of the strict options are backwards. They state: _`true` if `strict`; `false` otherwise_. The real default is _`true` unless `strict` is set to `false`_. All reasoning about loose/strict mode now requires inverse reasoning. I also strongly believe there’s no point in having a loose mode at all.
In the age of LLMs this is even more confusing. Code review tools now confidently tell users they must enable `strict` because every blog post from before 2026 in its training data repeats this. But this information is outdated.
---
I believe that the `strict` should be either not exist or be repurposed to its old meaning.
For the option to not exist, that means:
- In a minor version:
- Deprecate `strict`
- In a major version
- Decouple all related options from `strict`
- Remove the `strict` option
For the option to be repurposed to its old meaning, that means:
- In a minor version:
- Temporarily deprecate `strict`
- In a major version:
- Decouple all currently related options from `strict`
- Disable `strict` by default
- Link new options to strict mode. I believe `verbatimModuleSyntax` is a good candidate.
Contributor guide
Research direction
The issue names no source files or tests. Start by reviewing the `strict` option and related TypeScript compiler options, comparing the TypeScript 2.3 release notes with current behavior. Done requires choosing between removing `strict` and restoring its former meaning, then defining the corresponding migration and versioning changes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100