Skip to content

Deprecate alwaysStrict: false in TypeScript 6.0 - #63030

Closed
Ryan Cavanaugh (RyanCavanaugh) with Copilot wants to merge 19 commits into
mainfrom
copilot/assume-use-strict-default
Closed

Deprecate alwaysStrict: false in TypeScript 6.0#63030
Ryan Cavanaugh (RyanCavanaugh) with Copilot wants to merge 19 commits into
mainfrom
copilot/assume-use-strict-default

Conversation

CopilotAI commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

Deprecates alwaysStrict: false in 6.0 (will be removed in 7.0). This enables unconditional strict mode parsing, eliminating lookahead/reparse overhead for ambiguous constructs and simplifying AST caching across projects with different flags.

Changes

Deprecation warning in src/compiler/program.ts:

if(options.alwaysStrict===false){createDeprecatedDiagnostic("alwaysStrict","false",/*useInstead*/undefined,/*related*/undefined);}

User impact:

error TS5107: Option 'alwaysStrict=false' is deprecated and will stop functioning in TypeScript 7.0.
Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.

Tests:

  • alwaysStrictDeprecation.ts - verifies warning emission
  • alwaysStrictDeprecationSilenced.ts - verifies ignoreDeprecations: "6.0" silences warning
  • Updated programUpdates.ts test to add ignoreDeprecations: "6.0" to silence the deprecation warning in the updates-errors-when-strictNullChecks-changes test, allowing it to continue testing strictNullChecks changes without interference
  • Updated baseline for updates-errors-when-strictNullChecks-changes.js to reflect the silenced deprecation
Original prompt

This section details on the original issue you should resolve

<issue_title>Assume "use strict" everywhere by default</issue_title>
<issue_description>From #54500:

The alwaysStrict flag refers to inference of the "use strict"; directive. In TypeScript 6.0, all code will be assumed to be in "strict mode", which is a set of JS semantics that mostly affects syntactic corner cases around reserved words.

This lets us be faster because it's no longer necessary to look ahead or repase on constructs like

varx=await

which is legal "sloppy mode" referring to a variable named await. This also reduces the number of flags which possibly prevent sharing of source files between projects with different compiler settings.

See #61888 for RWC run; we found one codebase that used static as a parameter name.

This also lets us be a bit more efficient because our language service (and --build mode?) tries its best to reuse syntax trees for files belonging to multiple projects. When flags differ across projects, we have to sometimes cache ASTs by creating a composite key of both their paths and their projects' flags. If we can remove alwaysStrict, we can simplify our code and ensure syntax trees are shared more often. Over time, we may be able to remove all configuration flags that impact sharing.

We may need to clarify a few details here: specifically, are we removing--alwaysStrict, or just turning it on by default? If the former, that means that in 6.0 we are deprecating --alwaysStrict false.</issue_description>

Comments on the Issue (you are Copilot in this section)

Jake Bailey (@jakebailey) > We may need to clarify a few details here: specifically, are we removing --alwaysStrict, or just turning it on by default? If the former, that means that in 6.0 we are deprecating --alwaysStrict false.

I believe the right answer here is that we deprecate false in 6.0, and delete it entirely in 7.0.</comment_new>
<comment_new>Jake Bailey (@jakebailey)
Note that the implication here is that we unconditionally emit "use strict" in non-ESM files.</comment_new>


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

CopilotAIand others added 2 commits January 21, 2026 23:16
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
CopilotAI changed the title [WIP] Assume 'use strict' everywhere by defaultDeprecate alwaysStrict: false in TypeScript 6.0Jan 21, 2026
@RyanCavanaugh
Ryan Cavanaugh (RyanCavanaugh) marked this pull request as ready for review January 22, 2026 00:36
CopilotAI review requested due to automatic review settings January 22, 2026 00:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR deprecates the alwaysStrict: false compiler option in TypeScript 6.0, with full removal planned for 7.0. This change enables unconditional strict mode parsing, which eliminates lookahead/reparse overhead for ambiguous constructs and simplifies AST caching across projects with different compiler flags.

Changes:

  • Added deprecation warning for alwaysStrict: false in the compiler
  • Created test cases to verify deprecation warning emission and silencing behavior
  • Updated baseline for existing test affected by the deprecation warning

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
src/compiler/program.tsAdds deprecation check for alwaysStrict: false option
tests/cases/compiler/alwaysStrictDeprecation.tsTest case verifying deprecation warning is emitted
tests/cases/compiler/alwaysStrictDeprecationSilenced.tsTest case verifying warning can be silenced with ignoreDeprecations: "6.0"
tests/baselines/reference/alwaysStrictDeprecation.errors.txtExpected error output for deprecation warning
tests/baselines/reference/alwaysStrictDeprecation.jsExpected JavaScript output for deprecation test
tests/baselines/reference/alwaysStrictDeprecation.symbolsExpected symbol output for deprecation test
tests/baselines/reference/alwaysStrictDeprecation.typesExpected type output for deprecation test
tests/baselines/reference/alwaysStrictDeprecationSilenced.jsExpected JavaScript output when deprecation is silenced
tests/baselines/reference/alwaysStrictDeprecationSilenced.symbolsExpected symbol output when deprecation is silenced
tests/baselines/reference/alwaysStrictDeprecationSilenced.typesExpected type output when deprecation is silenced
tests/baselines/reference/tscWatch/programUpdates/updates-errors-when-strictNullChecks-changes.jsUpdated baseline now showing deprecation error instead of null check error

Comment threadtests/baselines/reference/alwaysStrictDeprecation.errors.txt

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot do as Jake says

Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
@jakebailey

Copy link
Copy Markdown
Member

TypeScript Bot (@typescript-bot) test it

@typescript-bot

TypeScript Bot (typescript-bot) commented Jan 23, 2026

Copy link
Copy Markdown
Contributor

Starting jobs; this comment will be updated as builds start and complete.

CommandStatusResults
test top400✅ Started✅ Results
user test this✅ Started✅ Results
run dt✅ Started✅ Results
perf test this faster✅ Started👀 Results

@typescript-bot

Copy link
Copy Markdown
Contributor

Hey Jake Bailey (@jakebailey), the results of running the DT tests are ready.

Everything looks the same!

You can check the log here.

@typescript-bot

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey) Here are the results of running the user tests with tsc comparing main and refs/pull/63030/merge:

There were infrastructure failures potentially unrelated to your change:

  • 1 instance of "Package install failed"
  • 1 instance of "Git clone failed"

Otherwise...

Everything looks good!

@typescript-bot

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey)
The results of the perf run you requested are in!

Here they are:

tsc

Comparison Report - baseline..pr
MetricbaselineprDeltaBestWorstp-value
Compiler-Unions - node (v18.15.0, x64)
Errors22~~~p=1.000 n=6
Symbols62,37062,370~~~p=1.000 n=6
Types50,38750,387~~~p=1.000 n=6
Memory used193,754k (± 0.94%)194,389k (± 1.01%)~192,568k196,217kp=0.378 n=6
Parse Time1.30s (± 0.42%)1.30s (± 0.49%)~1.29s1.31sp=0.201 n=6
Bind Time0.76s0.76s~~~p=1.000 n=6
Check Time9.86s (± 0.28%)9.89s (± 0.21%)~9.86s9.91sp=0.073 n=6
Emit Time2.74s (± 0.91%)2.74s (± 0.60%)~2.71s2.76sp=0.935 n=6
Total Time14.66s (± 0.30%)14.69s (± 0.21%)~14.65s14.74sp=0.146 n=6
angular-1 - node (v18.15.0, x64)
Errors22~~~p=1.000 n=6
Symbols955,823955,823~~~p=1.000 n=6
Types415,853415,853~~~p=1.000 n=6
Memory used1,253,904k (± 0.00%)1,253,899k (± 0.00%)~1,253,847k1,253,941kp=0.810 n=6
Parse Time6.54s (± 0.46%)6.53s (± 0.43%)~6.51s6.58sp=0.366 n=6
Bind Time1.96s1.96s (± 0.68%)~1.94s1.98sp=0.599 n=6
Check Time32.41s (± 0.32%)32.47s (± 0.27%)~32.32s32.55sp=0.297 n=6
Emit Time15.00s (± 0.33%)14.98s (± 0.33%)~14.91s15.04sp=0.469 n=6
Total Time55.91s (± 0.25%)55.94s (± 0.13%)~55.84s56.05sp=0.688 n=6
mui-docs - node (v18.15.0, x64)
Errors11,43911,439~~~p=1.000 n=6
Symbols2,700,2582,700,258~~~p=1.000 n=6
Types930,444930,444~~~p=1.000 n=6
Memory used3,036,168k (± 0.00%)3,036,130k (± 0.00%)~3,035,985k3,036,245kp=0.575 n=6
Parse Time8.59s (± 0.23%)8.59s (± 0.11%)~8.58s8.61sp=1.000 n=6
Bind Time2.30s (± 0.45%)2.30s (± 0.22%)~2.30s2.31sp=0.928 n=6
Check Time92.72s (± 0.74%)93.13s (± 0.32%)~92.77s93.44sp=0.229 n=6
Emit Time0.31s (± 2.41%)0.31s (± 3.19%)~0.30s0.32sp=0.554 n=6
Total Time103.93s (± 0.68%)104.34s (± 0.29%)~103.96s104.66sp=0.296 n=6
self-build-src - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols1,252,4471,252,449+2 (+ 0.00%)~~p=0.001 n=6
Types259,946259,946~~~p=1.000 n=6
Memory used2,387,987k (± 0.03%)2,508,754k (±11.83%)~2,387,113k3,115,333kp=0.689 n=6
Parse Time5.13s (± 0.43%)5.16s (± 1.25%)~5.10s5.28sp=0.294 n=6
Bind Time1.87s (± 0.63%)1.85s (± 0.93%)~1.82s1.87sp=0.050 n=6
Check Time35.47s (± 0.22%)35.60s (± 0.39%)~35.39s35.81sp=0.149 n=6
Emit Time2.97s (± 2.94%)3.01s (± 1.01%)~2.96s3.04sp=0.336 n=6
Total Time45.45s (± 0.24%)45.66s (± 0.34%)+0.21s (+ 0.46%)45.47s45.84sp=0.045 n=6
self-build-src-public-api - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols1,252,4471,252,449+2 (+ 0.00%)~~p=0.001 n=6
Types259,946259,946~~~p=1.000 n=6
Memory used2,941,345k (±12.73%)3,183,461k (± 0.02%)~3,182,697k3,184,290kp=0.378 n=6
Parse Time6.79s (± 1.75%)6.78s (± 0.68%)~6.71s6.84sp=0.575 n=6
Bind Time2.27s (± 0.71%)2.26s (± 1.13%)~2.23s2.30sp=0.575 n=6
Check Time42.93s (± 0.31%)43.06s (± 0.22%)~42.96s43.19sp=0.093 n=6
Emit Time3.52s (± 2.07%)3.48s (± 1.60%)~3.41s3.54sp=0.575 n=6
Total Time55.51s (± 0.42%)55.58s (± 0.20%)~55.43s55.70sp=0.688 n=6
self-compiler - node (v18.15.0, x64)
Errors00~~~p=1.000 n=6
Symbols264,690264,690~~~p=1.000 n=6
Types104,079104,079~~~p=1.000 n=6
Memory used443,079k (± 0.01%)443,091k (± 0.02%)~442,982k443,212kp=0.810 n=6
Parse Time3.51s (± 0.50%)3.52s (± 1.05%)~3.49s3.59sp=0.743 n=6
Bind Time1.39s (± 1.66%)1.37s (± 0.59%)~1.36s1.38sp=0.183 n=6
Check Time19.14s (± 0.35%)19.16s (± 0.43%)~19.08s19.30sp=0.573 n=6
Emit Time1.55s (± 0.68%)1.55s (± 0.67%)~1.53s1.56sp=0.801 n=6
Total Time25.59s (± 0.21%)25.59s (± 0.39%)~25.48s25.77sp=1.000 n=6
ts-pre-modules - node (v18.15.0, x64)
Errors7373~~~p=1.000 n=6
Symbols225,493225,493~~~p=1.000 n=6
Types94,37394,373~~~p=1.000 n=6
Memory used369,941k (± 0.05%)370,007k (± 0.08%)~369,735k370,374kp=0.689 n=6
Parse Time2.81s (± 0.74%)2.83s (± 0.79%)~2.79s2.85sp=0.190 n=6
Bind Time1.66s (± 1.17%)1.65s (± 0.49%)~1.64s1.66sp=0.869 n=6
Check Time16.64s (± 0.27%)16.63s (± 0.45%)~16.52s16.71sp=0.936 n=6
Emit Time0.00s0.00s (±244.70%)~0.00s0.01sp=0.405 n=6
Total Time21.11s (± 0.16%)21.11s (± 0.38%)~21.02s21.23sp=1.000 n=6
vscode - node (v18.15.0, x64)
Errors1111~~~p=1.000 n=6
Symbols4,157,4704,157,470~~~p=1.000 n=6
Types1,316,4801,316,480~~~p=1.000 n=6
Memory used3,950,721k (± 0.00%)3,950,611k (± 0.00%)~3,950,429k3,950,806kp=0.298 n=6
Parse Time16.04s (± 0.60%)16.10s (± 0.73%)~15.96s16.26sp=0.335 n=6
Bind Time5.52s (± 2.44%)5.57s (± 3.11%)~5.33s5.72sp=1.000 n=6
Check Time115.72s (± 2.72%)116.09s (± 3.16%)~112.62s119.93sp=0.575 n=6
Emit Time48.59s (± 4.85%)53.62s (±11.51%)~47.00s63.72sp=0.173 n=6
Total Time185.87s (± 2.95%)191.38s (± 3.94%)~181.56s197.90sp=0.230 n=6
webpack - node (v18.15.0, x64)
Errors4141~~~p=1.000 n=6
Symbols383,986383,986~~~p=1.000 n=6
Types167,978167,978~~~p=1.000 n=6
Memory used543,826k (± 0.03%)543,688k (± 0.02%)~543,511k543,898kp=0.173 n=6
Parse Time4.63s (± 0.75%)4.63s (± 0.42%)~4.60s4.65sp=1.000 n=6
Bind Time2.04s (± 0.91%)2.03s (± 1.06%)~2.00s2.06sp=0.871 n=6
Check Time23.68s (± 1.68%)23.82s (± 1.30%)~23.24s24.11sp=0.689 n=6
Emit Time0.00s0.00s~~~p=1.000 n=6
Total Time30.34s (± 1.31%)30.48s (± 1.02%)~29.89s30.75sp=0.688 n=6
xstate-main - node (v18.15.0, x64)
Errors3030~~~p=1.000 n=6
Symbols729,756729,756~~~p=1.000 n=6
Types218,510218,510~~~p=1.000 n=6
Memory used633,761k (± 0.01%)633,713k (± 0.00%)~633,685k633,742kp=0.066 n=6
Parse Time4.56s (± 0.39%)4.58s (± 0.78%)~4.52s4.62sp=0.226 n=6
Bind Time1.48s (± 0.82%)1.48s (± 0.35%)~1.48s1.49sp=1.000 n=6
Check Time22.02s (± 0.15%)22.10s (± 0.30%)+0.08s (+ 0.35%)22.03s22.19sp=0.037 n=6
Emit Time0.00s0.00s~~~p=1.000 n=6
Total Time28.07s (± 0.08%)28.17s (± 0.20%)+0.10s (+ 0.34%)28.12s28.26sp=0.005 n=6
System info unknown
Hosts
  • node (v18.15.0, x64)
Scenarios
  • Compiler-Unions - node (v18.15.0, x64)
  • angular-1 - node (v18.15.0, x64)
  • mui-docs - node (v18.15.0, x64)
  • self-build-src - node (v18.15.0, x64)
  • self-build-src-public-api - node (v18.15.0, x64)
  • self-compiler - node (v18.15.0, x64)
  • ts-pre-modules - node (v18.15.0, x64)
  • vscode - node (v18.15.0, x64)
  • webpack - node (v18.15.0, x64)
  • xstate-main - node (v18.15.0, x64)
BenchmarkNameIterations
Currentpr6
Baselinebaseline6

Developer Information:

Download Benchmarks

@typescript-bot

Copy link
Copy Markdown
Contributor

Jake Bailey (@jakebailey) Here are the results of running the top 400 repos with tsc comparing main and refs/pull/63030/merge:

Everything looks good!

@jakebailey

Copy link
Copy Markdown
Member

This PR seems correct enough, but alwaysStrict is a "strict option", so you can actually get false by setting strict: false in a config, so this won't actually detect the problem.

I think we might be forced to check getStrictOptionValue(compilerOptions, "alwaysStrict") and then somehow force everyone setting { "strict": false } to write { "strict": false, "alwaysStrict": true }, which sucks.

@jakebaileyJake Bailey (jakebailey) added the Breaking Change Would introduce errors in existing code label Jan 31, 2026
@github-project-automationgithub-project-automationBot moved this from Not started to Waiting on author in PR BacklogJan 31, 2026
@github-project-automationgithub-project-automationBot moved this to Not started in PR BacklogJan 31, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Breaking ChangeWould introduce errors in existing codeFor Milestone BugPRs that fix a bug with a specific milestone

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Deprecate --useStrict & assume "use strict" everywhere by default

6 participants

@jakebailey@typescript-bot@RyanCavanaugh@DanielRosenwasser