Skip to content

Instantly share code, notes, and snippets.

@privatenumber
Created February 24, 2026 13:21
Show Gist options
  • Select an option

  • Save privatenumber/3d2e80da28f84ee30b77d53e1693378f to your computer and use it in GitHub Desktop.

Select an option

Save privatenumber/3d2e80da28f84ee30b77d53e1693378f to your computer and use it in GitHub Desktop.
TypeScript 5.x to 6.0 Migration Guide

TypeScript 5.x to 6.0 Migration Guide

TypeScript 6.0 is a transition release bridging 5.9 and the forthcoming 7.0 (a native Go port). Most changes are new defaults and deprecations preparing for 7.0. Here is what you need to do:

Most projects need these tsconfig changes:

{
    "compilerOptions": {
        "types": ["node"],           // @types are no longer auto-discovered (see §1.6)
        "rootDir": "./src"           // no longer inferred from source files (see §1.5)
    }
}

You may also need to:

  • Set "strict": false if your project is not ready for strict mode (now the default -- see §1.1)
  • Set explicit target, module, or moduleResolution if you relied on old defaults (see §1.2--§1.4)
  • Remove deprecated options like baseUrl, outFile, downlevelIteration (see §2)
  • Replace assert { } with with { } on imports (see §2.11)

Automated migration: The ts5to6 tool handles the two most disruptive changes (baseUrl removal and rootDir inference) automatically.

Escape hatch: Add "ignoreDeprecations": "6.0" to silence deprecation warnings temporarily. This will not work in TypeScript 7.0.

Context and motivation

TypeScript 6.0 is the last release based on the JavaScript codebase. TypeScript 7.0 will be a native port written in Go that leverages shared-memory multi-threading for dramatically faster type checking.

The JS codebase is now in maintenance mode -- only critical fixes, deprecation work, and 6.0/7.0 alignment changes will be merged. Most open PRs against the JS codebase will not be merged. All language service bugs have been bulk-closed since the Go rewrite uses LSP from scratch -- if you hit an editor bug, test it in the TypeScript Native Nightly extension and file against typescript-go if it still repros.

The majority of changes in TypeScript 6.0 are about alignment and preparation for TypeScript 7.0: new defaults that reflect the modern ecosystem, deprecations of legacy options that the Go-based compiler will not support, and a diagnostic migration flag (--stableTypeOrdering) to help compare output between the two codebases.

6.0 also ships genuine new features: improved type inference for methods, #/ subpath imports, es2025 target/lib, Temporal types, and several new standard library additions.

Release timeline

From the TypeScript 6.0 Iteration Plan:

Table of Contents

  1. New Default Values
  2. Deprecations
  3. The ignoreDeprecations Mechanism
  4. New Features
  5. New Standard Library Types
  6. Breaking Behavioral Changes
  7. Migration Checklist
  8. Appendix: All Referenced Pull Requests
  9. Appendix: Referenced GitHub Issues
  10. Resources

1. New Default Values

TypeScript 6.0 changes several compiler option defaults. These changes reflect the reality that virtually every runtime is evergreen, ESM is dominant, and stricter typing is universally preferred.

Full tsconfig reference for restoring 5.9 behavior
{
    "compilerOptions": {
        // Most projects need these (§1.5, §1.6):
        "rootDir": "./src",               // was inferred from input files, now defaults to "."
        "types": ["node"],                 // was all @types, now defaults to none

        // Set explicitly if you relied on old defaults (§1.1-§1.4):
        // "strict": false,               // now true by default
        // "target": "es2020",            // now es2025 by default
        // "module": "commonjs",          // now es2022 (resolved from target)
        // "moduleResolution": "nodenext", // now bundler (resolved from module)

        // Rarely needed (§1.7-§1.10):
        // "noUncheckedSideEffectImports": false,  // now true
        // "libReplacement": true,                 // now false
        // "esModuleInterop": true,                // already was true for most configs
        // "allowSyntheticDefaultImports": true     // already was true for most configs
    }
}

Note: rootDir only matters if you emit files (i.e., you have outDir set). If you use TypeScript only for type-checking (noEmit: true) with an external bundler like esbuild/Rollup/Vite, you don't need to set rootDir at all -- the new default won't affect you.

1.1 strict defaults to true

PR: #63087 | Issue: #62333

Previously false. Now true.

Impact: Projects that relied on strict: false implicitly will now see errors from strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables, and alwaysStrict.

Migration:

  {
      "compilerOptions": {
+         "strict": false  // only if you need to opt out
      }
  }
Source code

Source: src/compiler/commandLineParser.ts:906-916

{
    name: "strict",
    type: "boolean",
    // ...
    defaultValueDescription: true,
}

1.2 target defaults to es2025 (the current-year ES version)

PR: #63067 | Issues: #62198, #62196

Previously inferred as ES3. Now defaults to ScriptTarget.LatestStandard, which is ES2025.

Impact: If your project targets older runtimes, you need to set target explicitly. No downlevel transforms will be applied by default (e.g., no class field transpilation, no async/await transpilation).

Source code

Source: src/compiler/types.ts:7686-7690

ES2025 = 12,
ESNext = 99,
JSON = 100,
Latest = ESNext,
LatestStandard = ES2025,

The computed default is applied in src/compiler/utilities.ts:9048-9053:

target: {
    dependencies: [],
    computeValue: compilerOptions => {
        const target = compilerOptions.target === ScriptTarget.ES3 ? undefined : compilerOptions.target;
        return target ?? ScriptTarget.LatestStandard;
    },
},

Note that ES3 is treated as undefined and falls through to LatestStandard, effectively making ES3 a no-op even before its deprecation diagnostic fires.

1.3 module resolves to es2022 (documented as esnext)

PR: #62669

The module kind is now computed from the target. With target defaulting to ES2025 (which is >= ES2022), the resolved module will be ES2022. In practice, when no module or target is explicitly set, you get ES2022 module output (which supports top-level await).

Impact: Projects that relied on CommonJS output by default must now explicitly set "module": "commonjs".

How the module default is computed

The logic is at src/compiler/utilities.ts:9055-9076:

module: {
    dependencies: ["target"],
    computeValue: (compilerOptions): ModuleKind => {
        if (typeof compilerOptions.module === "number") {
            return compilerOptions.module;
        }
        const target = _computedOptions.target.computeValue(compilerOptions);
        if (target === ScriptTarget.ESNext) {
            return ModuleKind.ESNext;
        }
        if (target >= ScriptTarget.ES2022) {
            return ModuleKind.ES2022;
        }
        // ...
    },
},

The commandLineParser.ts declares the default description as esnext for documentation purposes.

1.4 moduleResolution defaults to bundler

PR: #62669

The module resolution default is computed from the module kind. Since the default module kind is now ES2022 (which is not None/AMD/UMD/System/NodeNext/Node16+), the fallback is ModuleResolutionKind.Bundler.

Impact: Projects that relied on node10 resolution by default may see different module resolution behavior. If you target Node.js directly, set "moduleResolution": "nodenext".

How the moduleResolution default is computed

Source: src/compiler/utilities.ts:9077-9098

moduleResolution: {
    dependencies: ["module", "target"],
    computeValue: (compilerOptions): ModuleResolutionKind => {
        if (compilerOptions.moduleResolution !== undefined) {
            return compilerOptions.moduleResolution;
        }
        const moduleKind = _computedOptions.module.computeValue(compilerOptions);
        switch (moduleKind) {
            case ModuleKind.None:
            case ModuleKind.AMD:
            case ModuleKind.UMD:
            case ModuleKind.System:
                return ModuleResolutionKind.Classic;
            case ModuleKind.NodeNext:
                return ModuleResolutionKind.NodeNext;
        }
        if (ModuleKind.Node16 <= moduleKind && moduleKind < ModuleKind.NodeNext) {
            return ModuleResolutionKind.Node16;
        }
        return ModuleResolutionKind.Bundler;
    },
},

1.5 rootDir defaults to . (directory of tsconfig.json)

PR: #62418

Previously, rootDir was inferred from the common source directory of all input files. Now, when a tsconfig.json exists, it defaults to the directory containing that file ("${configDir}").

Note

This is not the same as the similarly-named option rootDirs, which continues to work the same in both 6.0 and 7.0.

Impact: rootDir controls what path prefix gets stripped from source file paths when placing them under outDir. Consider a typical project layout:

my-project/
├── tsconfig.json        ← rootDir now defaults to here (".")
├── src/
│   ├── index.ts
│   └── utils.ts
└── dist/                ← outDir

In TypeScript 5.9, with no explicit rootDir, TypeScript would scan all input files, compute their common directory (src/), and use that as rootDir. So src/index.ts would strip src/ and emit to dist/index.js.

In TypeScript 6.0, rootDir defaults to the tsconfig.json directory (.), not the computed common directory. So src/index.ts now strips . (the project root) and preserves the src/ prefix in the output:

# TypeScript 5.9 (rootDir inferred as "src/")
dist/index.js
dist/utils.js

# TypeScript 6.0 (rootDir defaults to ".")
dist/src/index.js        ← unexpected nesting!
dist/src/utils.js

You'll know this is the issue if files start appearing at dist/src/index.js instead of dist/index.js after upgrading.

TypeScript will error in common cases. The PR didn't just silently change the output layout -- it added a safety net. When all of these conditions are true:

  • noEmit is not set (you're actually emitting files)
  • composite is not set (composite projects already had this behavior)
  • rootDir is not explicitly set
  • A tsconfig.json exists
  • outDir, declarationDir, or outFile is specified

...TypeScript computes what the old 5.9 inferred root would have been (getComputedCommonSourceDirectory), compares it to the new default (the tsconfig directory), and if they differ, emits diagnostic 5011:

The common source directory of 'tsconfig.json' is './src'.
The 'rootDir' setting must be explicitly set to this or another path
to adjust your output's file layout.

So you won't get silently wrong output -- you'll get an error telling you exactly what to set rootDir to.

Migration:

  {
      "compilerOptions": {
+         "rootDir": "./src"
      },
      "include": ["./src"]
  }

Note that this often means both rootDir and include end up specifying the same directory, which feels redundant but is intentional -- include controls which files are part of the project, while rootDir controls the output directory structure.

The ts5to6 migration tool can automatically adjust rootDir across your codebase.

Implementation details

This change was motivated by two things (#62194):

  1. Performance: The old behavior required computing the full set of input files just to determine the output directory structure. With the new default, the output structure is known immediately from the tsconfig location.
  2. Language service: The new behavior lets the language service trivially determine whether a file could belong to a given tsconfig.json without loading and parsing the project first.

The actual code change (commit 7affa9e540) was a single-word removal in getCommonSourceDirectory:

- else if (options.composite && options.configFilePath) {
+ else if (options.configFilePath) {

Before (5.9): The tsconfig-directory fallback only applied when composite: true (project references mode). For regular non-composite projects, it fell through to computeCommonSourceDirectoryOfFilenames -- a function that scans every input file path and computes their longest common directory prefix.

After (6.0): The options.composite guard was removed. Now any project with a tsconfig.json uses the config file's directory as rootDir. The same guard removal was applied in src/compiler/utilities.ts and src/compiler/moduleNameResolver.ts.

The safety-net diagnostic is implemented at src/compiler/program.ts:4259-4286.

1.6 types defaults to []

PR: #63054 | Issue: #62195

Previously, TypeScript auto-discovered all @types packages in node_modules/@types. Now it defaults to an empty array, meaning no ambient type packages are auto-included.

Impact: This is the change that will affect the most projects. You will see errors like:

  • Cannot find name 'process'
  • Cannot find name 'describe'
  • Cannot find module 'fs'
  • Cannot find name 'Buffer'

Migration:

  {
      "compilerOptions": {
+         "types": ["node"]
      }
  }

Or for test projects:

  {
      "compilerOptions": {
+         "types": ["node", "jest"]
      }
  }

To restore the old behavior (auto-discover all @types):

  {
      "compilerOptions": {
+         "types": ["*"]
      }
  }

Note

  • "types": ["*"] is a special token, not a glob pattern. Patterns like "node*" will not work.
  • Omitting types now means "include none" (previously "include all"). Setting types: null also means "include none".
  • Many projects have seen 20-50% build time improvements from explicitly specifying types instead of auto-discovering hundreds of transitive @types packages.
Source code

Source: src/compiler/moduleNameResolver.ts:813-816

export function getAutomaticTypeDirectiveNames(options: CompilerOptions, host: ModuleResolutionHost): string[] {
    if (!usesWildcardTypes(options)) {
        return options.types ?? [];
    }
    // ...
}

1.7 noUncheckedSideEffectImports defaults to true

PR: #62443 | Issue: #62421

Previously false. Now true.

Impact: Side-effect-only imports (e.g., import "./polyfill") will now be checked for resolution. If TypeScript cannot find the module, it will report an error. This catches typos like import "./polyfil".

Migration: If you have side-effect imports that intentionally don't resolve (e.g., CSS imports handled by a bundler), set "noUncheckedSideEffectImports": false.

Source code

Source: src/compiler/commandLineParser.ts:1273-1281

{
    name: "noUncheckedSideEffectImports",
    type: "boolean",
    affectsSemanticDiagnostics: true,
    affectsBuildInfo: true,
    category: Diagnostics.Modules,
    description: Diagnostics.Check_side_effect_imports,
    defaultValueDescription: true,
},

1.8 libReplacement defaults to false

PR: #62391 | Issue: #62214

Previously true. Now false.

Impact: libReplacement previously caused TypeScript to attempt module resolution for every lib file (e.g., trying to resolve @typescript/lib-es2020). In most projects this never finds anything and just adds overhead in the form of failed resolutions and extra watch locations. Disabling it by default improves performance.

Migration: If you use @typescript/lib-* replacement packages, set "libReplacement": true.

Source code

Source: src/compiler/commandLineParser.ts:895-902

{
    name: "libReplacement",
    type: "boolean",
    affectsProgramStructure: true,
    category: Diagnostics.Language_and_Environment,
    description: Diagnostics.Enable_lib_replacement,
    defaultValueDescription: false,
},

1.9 esModuleInterop defaults to true

PR: #62567 | Issue: #62529

Previously false. Now true.

Impact: import express from "express" (default import from CJS) now always works. Setting esModuleInterop: false is deprecated (see section 2.7).

Source code

Source: src/compiler/commandLineParser.ts:1189-1197

{
    name: "esModuleInterop",
    // ...
    defaultValueDescription: true,
},

1.10 allowSyntheticDefaultImports defaults to true

PR: #62567

Previously dependent on other settings. Now always true.

Impact: Minimal. This was already effectively true for most configurations. The change means import React from 'react' always works without explicit opt-in.

Source code

Source: src/compiler/commandLineParser.ts:1180-1186

{
    name: "allowSyntheticDefaultImports",
    // ...
    defaultValueDescription: true,
},

Summary of Default Changes

Option 5.9 Default 6.0 Default
strict false true
target ES3 es2025 (LatestStandard)
module CommonJS (varies) es2022 (resolved from target; documented as esnext)
moduleResolution node10 (varies) bundler (resolved from module)
rootDir inferred from input files . (tsconfig.json directory)
types ["*"] (all @types) [] (none)
noUncheckedSideEffectImports false true
libReplacement true false
esModuleInterop false true
allowSyntheticDefaultImports varies true

2. Deprecations

All deprecations in TypeScript 6.0 will become hard removals in TypeScript 7.0. They can be temporarily silenced (see section 3).

Full list of deprecated options (source code)

The full list is in a single block at src/compiler/program.ts:4528-4559:

checkDeprecations("6.0", "7.0", createDiagnostic, createDeprecatedDiagnostic => {
    if (options.alwaysStrict === false) {
        createDeprecatedDiagnostic("alwaysStrict", "false");
    }
    if (options.target === ScriptTarget.ES5) {
        createDeprecatedDiagnostic("target", "ES5");
    }
    if (options.moduleResolution === ModuleResolutionKind.Node10) {
        createDeprecatedDiagnostic("moduleResolution", "node10");
    }
    if (options.moduleResolution === ModuleResolutionKind.Classic) {
        createDeprecatedDiagnostic("moduleResolution", "classic");
    }
    if (options.baseUrl !== undefined) {
        createDeprecatedDiagnostic("baseUrl");
    }
    if (options.esModuleInterop === false) {
        createDeprecatedDiagnostic("esModuleInterop", "false");
    }
    if (options.allowSyntheticDefaultImports === false) {
        createDeprecatedDiagnostic("allowSyntheticDefaultImports", "false");
    }
    if (options.outFile) {
        createDeprecatedDiagnostic("outFile");
    }
    if (options.module === ModuleKind.None || options.module === ModuleKind.AMD ||
        options.module === ModuleKind.UMD || options.module === ModuleKind.System) {
        createDeprecatedDiagnostic("module", ModuleKind[options.module]);
    }
    if (options.downlevelIteration !== undefined) {
        createDeprecatedDiagnostic("downlevelIteration");
    }
});

2.1 target: es3 and es5 (deprecated)

PR: #63067 | Issue: #62196

Both es3 and es5 targets are deprecated. ES5 was important for Internet Explorer, but IE is retired and ES2015 was released over a decade ago. The lowest supported target is now ES2015.

Migration: Change target to es2015 or higher.

If you still need ES5 output, use an external compiler to post-process TypeScript's output:

  • esbuild: target: "es5"
  • SWC: swc dist/esm -d dist/es5
  • Vite: build.target
  • You can also use TS 6.x for emit and TS 7.x for type-checking only (--noEmit)

With ES5 gone, TypeScript no longer emits __extends, __generator/__awaiter, or __spreadArray helpers for the minimum target.

Deprecated key registration

Source: src/compiler/commandLineParser.ts:596

deprecatedKeys: new Set(["es3", "es5"]),

2.2 --downlevelIteration (deprecated)

PR: #63071

downlevelIteration only had effect when targeting below ES2015 (ES3 or ES5). Since both are deprecated, this flag is now meaningless. Setting it to any value (even false) triggers a deprecation error.

Migration: Remove downlevelIteration from your tsconfig.json entirely.

  • The flag was already a no-op for projects targeting ES2015+. Many major projects (Zod, SWR, Sentry, tldraw) had it set despite targeting ES2015+ where it had zero effect.
  • If you inherit downlevelIteration from a shared base tsconfig you don't control, set "downlevelIteration": null in your config to neutralize the inherited value.
Source code

Source: src/compiler/program.ts:4556-4557

if (options.downlevelIteration !== undefined) {
    createDeprecatedDiagnostic("downlevelIteration");
}

2.3 --moduleResolution node / node10 (deprecated)

PR: #62338 | Issue: #62200

node10 encoded Node.js 10's resolution algorithm, which predates ESM support, exports fields, self-name imports, and many other modern features. It is no longer representative of how Node.js resolves modules.

Migration:

  • Targeting Node.js directly: use "moduleResolution": "nodenext"
  • Using a bundler or Bun: use "moduleResolution": "bundler"

What breaks when switching from node10 to nodenext:

  • Extensionless relative imports (import "./foo" must become import "./foo.js")
  • Packages without exports fields may resolve differently
  • CJS/ESM file distinction is enforced

Projects using --module commonjs without explicit moduleResolution will now get bundler resolution instead of node10 -- this is a silent default change.

Deprecated key registration

Source: src/compiler/commandLineParser.ts:1107

deprecatedKeys: new Set(["node", "node10", "classic"]),

2.4 --moduleResolution classic (deprecated)

PR: #62669 | Issue: #62206

classic was TypeScript's original module resolution algorithm from before Node.js resolution became the de facto standard. No practical use case remains for it.

Migration: Use "moduleResolution": "nodenext" or "moduleResolution": "bundler".

2.5 --module amd, umd, system, none (deprecated)

PR: #62669 | Issue: #62199

AMD, UMD, and SystemJS were important when browsers lacked native module support. ESM is now universal. none (no module system) is also deprecated.

Migration: Use "module": "esnext", "module": "preserve", "module": "commonjs", "module": "nodenext", or adopt a bundler.

  • This also implies dropped support for the amd-module directive.
  • module: none is also deprecated (not prominently mentioned in the blog post). allowUmdGlobalAccess and export as namespace are NOT deprecated -- they are independent of the module format.
  • Users who had module: es2020 (or similar) without explicit moduleResolution were previously getting classic resolution. After 6.0, they'll get bundler instead -- a silent behavior change.
Deprecated key registration

Source: src/compiler/commandLineParser.ts:625

deprecatedKeys: new Set(["none", "amd", "system", "umd"]),

2.6 --baseUrl (deprecated)

PR: #62509 | Issue: #62207

baseUrl was most commonly used as a prefix for paths entries, but it also acted as a lookup root for module resolution -- meaning import "foo" could silently resolve to src/foo.ts even when the developer only intended path-mapping for @app/* and @lib/*.

paths has not required baseUrl for a long time. In 6.0, baseUrl is deprecated and no longer serves as a module lookup root.

Migration: Inline the baseUrl prefix into your paths entries:

  {
      "compilerOptions": {
-         "baseUrl": "./src",
          "paths": {
-             "@app/*": ["app/*"],
-             "@lib/*": ["lib/*"]
+             "@app/*": ["./src/app/*"],
+             "@lib/*": ["./src/lib/*"]
          }
      }
  }

If you actually used baseUrl as a module lookup root (rare), add a catch-all path:

{
    "compilerOptions": {
        "paths": {
            "*": ["./src/*"],
            "@app/*": ["./src/app/*"],
            "@lib/*": ["./src/lib/*"]
        }
    }
}

The ts5to6 migration tool can automatically remove baseUrl and rewrite paths entries across your codebase, including the extends interaction case.

Note

extends interaction pain point: When a base tsconfig defines paths and extending configs set baseUrl, the paths were effectively reinterpreted against each extending config's baseUrl. After removing baseUrl, paths resolve strictly relative to the config file where they're defined. This means projects with shared base configs may need to define paths in more locations. extends does NOT merge paths -- they are always fully overridden.

Source code

src/compiler/program.ts:4541-4542

2.7 --esModuleInterop false and --allowSyntheticDefaultImports false (deprecated)

PR: #62567 | Issue: #62529

These options can no longer be set to false. The safer interop behavior is always enabled. Both default to true.

Migration: Remove explicit false values. Change namespace imports to default imports where needed:

- import * as express from "express";
+ import express from "express";

Warning

This is a runtime behavior change, not just type-checking. With esModuleInterop: true, TypeScript now emits __importDefault/__importStar helpers (or imports them from tslib) that check for the __esModule marker at runtime. The emit for import x from "./cjs" changes from require("./cjs").default to a helper-wrapped call.

For projects wanting maximum correctness with CJS interop, verbatimModuleSyntax is the recommended stricter alternative.

Source code

src/compiler/program.ts:4544-4549

2.8 --alwaysStrict false (deprecated)

PR: #63089 | Issue: #62213

All code is now assumed to be in JavaScript strict mode.

Impact:

  • TypeScript will now unconditionally emit "use strict" in non-ESM files. ESM files are already strict by spec, so this only affects CommonJS output.
  • Strict mode reserves these identifiers: implements, interface, let, package, private, protected, public, static, yield. Any of these used as variable/parameter/function names in non-module, non-strict code will break.

Migration: Remove alwaysStrict: false from your tsconfig. If you have "sloppy mode" code that uses reserved words like await, static, private, or public as regular identifiers, rename them.

Source code

src/compiler/program.ts:4529-4531

2.9 --outFile (deprecated)

PR: #62981

outFile concatenated multiple inputs into a single output file. Modern bundlers (Webpack, Rollup, esbuild, Vite, Parcel) do this faster and with more features.

Migration: Use a bundler instead.

  • Zero community members raised concerns about outFile removal in the deprecation tracking issue (#54500). Top-800 repo tests showed no breakage, confirming negligible real-world usage.
  • Users of outFile typically also used module: amd/umd/system -- the entire ecosystem (AMD/SystemJS concatenation + global scripts via module: none + ES5 downleveling) is being removed simultaneously.
Source code

src/compiler/program.ts:4550-4551

2.10 Legacy module keyword for namespaces (deprecated)

PR: #62876 | Issue: #62211

Using module Foo { ... } to declare a namespace is now a hard error. This is necessary because module blocks are a potential ECMAScript proposal that would conflict with the legacy TypeScript syntax.

Migration: Replace module Foo { ... } with namespace Foo { ... }.

  • Ambient module declarations remain fully supported: declare module "some-module" { ... } still works.
  • declare module foo { (unquoted/bare identifier) is also deprecated. Only declare module "specifier" {} (quoted string) remains valid.
  • This applies to .d.ts files too. If a dependency on npm uses module Foo {} in its declarations, remediation options are: upgrade the dependency, fork it, or use patch-package. DefinitelyTyped was fully cleaned up over two years ago, so @types packages are not affected.
Source code

The error is emitted in the checker at src/compiler/checker.ts:48164:

if (!(node.flags & (NodeFlags.Namespace | NodeFlags.GlobalAugmentation))) {
    error(node.name, Diagnostics.A_namespace_declaration_should_not_be_declared_using_the_module_keyword_Please_use_the_namespace_keyword_instead);
}

2.11 asserts keyword on imports (deprecated)

PR: #63077 | Issue: #62210

The import assertions proposal (assert { type: "json" }) was replaced by the import attributes proposal (with { type: "json" }). The assert syntax is now a deprecation error.

Migration:

- import blob from "./data.json" assert { type: "json" }
+ import blob from "./data.json" with { type: "json" }

The rename from assert to with is not just cosmetic -- import attributes (with) can influence how a module is loaded/interpreted, while assertions (assert) could only validate properties. In practice for { type: "json" } the behavior is the same.

Source code

src/compiler/checker.ts:48616-48620

2.12 /// <reference no-default-lib="true"/> (deprecated)

PR: #62435

This directive was largely misunderstood and misused. It is parsed but ignored.

Migration: Use --noLib or --libReplacement instead.

  • The directive previously had two effects: suppressed default lib inclusion AND marked the file as a "default library" itself (making skipDefaultLibCheck apply to it). Both behaviors are removed.
  • sourceFile.hasNoDefaultLib is now always false in the compiler API. Use program.isSourceFileDefaultLibrary(file) instead.
Source code

src/compiler/parser.ts:10636

Deprecation Summary Table

Deprecated Option/Value Replacement PR
target: es3 / es5 es2015 or higher #63067
downlevelIteration Remove entirely #63071
moduleResolution: node / node10 nodenext or bundler #62338
moduleResolution: classic nodenext or bundler #62669
module: amd / umd / system / none esnext, preserve, commonjs, nodenext #62669
baseUrl Inline into paths entries #62509
esModuleInterop: false Remove (always true) #62567
allowSyntheticDefaultImports: false Remove (always true) #62567
alwaysStrict: false Remove (always strict) #63089
outFile Use a bundler #62981
module Foo { } syntax namespace Foo { } #62876
assert { } on imports with { } #63077
/// <reference no-default-lib="true"/> --noLib or --libReplacement #62435

3. The ignoreDeprecations Mechanism

All 6.0 deprecations can be temporarily silenced by setting "ignoreDeprecations": "6.0" in your tsconfig.json. This is intended as a transitional aid, not a permanent solution -- TypeScript 7.0 will hard-remove all deprecated options regardless of ignoreDeprecations.

How It Works

Valid values are "5.0" and "6.0". Any other value produces diagnostic 5103: "Invalid value for '--ignoreDeprecations'."

A deprecation warning fires only if ignoreDeprecationsVersion < deprecatedInVersion. Setting "ignoreDeprecations": "6.0" means 6.0 < 6.0 is false, so the 6.0 deprecation warnings are suppressed.

Implementation details

Option definition: src/compiler/commandLineParser.ts:1683-1687

{
    name: "ignoreDeprecations",
    type: "string",
    defaultValueDescription: undefined,
}

Version validation: src/compiler/program.ts:4428-4437

function getIgnoreDeprecationsVersion(): Version {
    const ignoreDeprecations = options.ignoreDeprecations;
    if (ignoreDeprecations) {
        if (ignoreDeprecations === "5.0" || ignoreDeprecations === "6.0") {
            return new Version(ignoreDeprecations);
        }
        reportInvalidIgnoreDeprecations();  // Diagnostic 5103
    }
    return Version.zero;
}

Silencing logic: src/compiler/program.ts:4439-4473

The checkDeprecations function compares three versions:

  1. deprecatedInVersion -- the version where the option was deprecated (e.g., "6.0")
  2. removedInVersion -- the version where it will be removed (e.g., "7.0")
  3. ignoreDeprecationsVersion -- the user's ignoreDeprecations value

Diagnostic Codes

Code Message
5101 Option '{0}' is deprecated and will stop functioning in TypeScript {1}. Specify compilerOption '"ignoreDeprecations": "{2}"' to silence this error.
5102 Option '{0}' has been removed. Please remove it from your configuration.
5103 Invalid value for '--ignoreDeprecations'.
5107 Option '{0}={1}' is deprecated and will stop functioning in TypeScript {2}. Specify compilerOption '"ignoreDeprecations": "{3}"' to silence this error.
5108 Option '{0}={1}' has been removed. Please remove it from your configuration.
5111 Visit https://aka.ms/ts6 for migration information.

These are defined in src/compiler/diagnosticMessages.json.

Migration URL

Several deprecation diagnostics include the related message "Visit https://aka.ms/ts6 for migration information" (diagnostic 5111). This appears for baseUrl and moduleResolution: node10 deprecations.


4. New Features

4.1 Less Context-Sensitivity on this-less Functions

PR: #62243 (by Mateusz Burzynski / Andarist)

This is a type inference improvement. Previously, method-syntax functions in object literals were always treated as "contextually sensitive" because they have an implicit this parameter. This prevented TypeScript from using them as inference sources for generic type parameters during the first inference pass.

Now, if the function body never actually references this, the function is not considered contextually sensitive and participates in the first inference pass. This fixes the ordering-dependent inference failure where method-syntax functions would fail to infer types when defined before the function that provides the inference source.

What changed in the compiler

The root cause was in src/compiler/utilities.ts:10880-10897:

export function hasContextSensitiveParameters(node: FunctionLikeDeclaration): boolean {
    // Functions with type parameters are not context sensitive.
    if (!node.typeParameters) {
        // Functions with any parameters that lack type annotations are context sensitive.
        if (some(node.parameters, p => !getEffectiveTypeAnnotationNode(p))) {
            return true;
        }
        if (node.kind !== SyntaxKind.ArrowFunction) {
            // If the first parameter is not an explicit 'this' parameter, then the function has
            // an implicit 'this' parameter which is subject to contextual typing.
            const parameter = firstOrUndefined(node.parameters);
            if (!(parameter && parameterIsThisKeyword(parameter))) {
                return !!(node.flags & NodeFlags.ContainsThis);
            }
        }
    }
    return false;
}

The key change is at line 10892: instead of unconditionally returning true for non-arrow functions without an explicit this parameter, it now checks node.flags & NodeFlags.ContainsThis -- a flag defined at src/compiler/types.ts:793:

ContainsThis = 1 << 8,  // Interface contains references to "this"

The isThislessFunctionLikeDeclaration family (defined at src/compiler/checker.ts:13664-13690) complements this by checking type annotations:

function isThislessFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
    const returnType = getEffectiveReturnTypeNode(node);
    const typeParameters = getEffectiveTypeParameterDeclarations(node);
    return (node.kind === SyntaxKind.Constructor || (!!returnType && isThislessType(returnType))) &&
        node.parameters.every(isThislessVariableLikeDeclaration) &&
        typeParameters.every(isThislessTypeParameter);
}

Practical effect:

declare function callIt<T>(obj: {
    produce: (x: number) => T,
    consume: (y: T) => void,
}): void;

// Before 6.0: Error on y ('unknown')
// After 6.0: Works, y inferred as number
callIt({
    consume(y) { return y.toFixed(); },
    produce(x: number) { return x * 2; },
});

This PR fixes 9 issues: #62204, #60986, #58630, #57572, #56067, #55489, #55124, #53924, #50258.

Potential regressions:

  • Code that previously relied on methods being deferred (context-sensitive) may now infer types earlier, potentially with less contextual information.
  • VS Code had 5 new errors from this change.
  • The effect library initially broke (but was fixed in the final PR).
  • Libraries using patterns where this-less methods accidentally got correct types through deferred inference may see type changes.

4.2 Subpath Imports Starting with #/

PR: #62844 (by magic-akari)

Node.js previously required something after # in subpath imports. Node.js PR #60864 added support for #/ as a prefix. TypeScript now supports this under node20, nodenext, and bundler module resolution.

Implementation details

A new ImportsPatternRoot feature flag at src/compiler/moduleNameResolver.ts:1698-1707:

// allowing `#/` root imports in package.json imports field
// not supported until mass adoption - https://github.com/nodejs/node/pull/60864
ImportsPatternRoot = 1 << 6,
AllFeatures = Imports | SelfName | Exports | ExportsPatternTrailers | ImportsPatternRoot,

Node16Default = Imports | SelfName | Exports | ExportsPatternTrailers,

NodeNextDefault = AllFeatures,
BundlerDefault = Imports | SelfName | Exports | ExportsPatternTrailers | ImportsPatternRoot,

Note that Node16Default does not include ImportsPatternRoot, while NodeNextDefault and BundlerDefault do. This reflects the fact that Node.js 16 doesn't support #/, but newer versions (20+) and bundlers do.

The guard is at src/compiler/moduleNameResolver.ts:2657:

if (moduleName === "#" || (startsWith(moduleName, "#/") && !(state.features & NodeResolutionFeatures.ImportsPatternRoot))) {

When the ImportsPatternRoot feature is enabled, #/ imports pass through to the imports field resolution logic instead of being rejected.

Usage:

{
    "name": "my-package",
    "type": "module",
    "imports": {
        "#": "./dist/index.js",
        "#/*": "./dist/*"
    }
}
import * as utils from "#/utils.js";

Supported in newer Node.js 20 releases (backported). Not available under --moduleResolution node16 since that Node.js version predates the feature. The motivating pattern is "imports": { "#/*": "./src/*" } mirroring "exports": { "./*": "./src/*" }.

4.3 --moduleResolution bundler with --module commonjs

PR: #62320

Previously, --moduleResolution bundler could only be used with --module esnext or --module preserve. Now it also allows --module commonjs.

Source code

Source: src/compiler/program.ts:4366-4368

if (moduleResolution === ModuleResolutionKind.Bundler &&
    !emitModuleKindIsNonNodeESM(moduleKind) &&
    moduleKind !== ModuleKind.Preserve &&
    moduleKind !== ModuleKind.CommonJS) {
    createOptionValueDiagnostic("moduleResolution",
        Diagnostics.Option_0_can_only_be_used_when_module_is_set_to_preserve_commonjs_or_es2015_or_later, "bundler");
}

The addition of moduleKind !== ModuleKind.CommonJS means CommonJS now passes the validation.

This provides a migration path for projects deprecating --moduleResolution node10 that still emit CommonJS.

Recommended migration paths:

  • Bundled web apps / Bun: --module preserve + --moduleResolution bundler
  • Node.js apps: --module nodenext
  • Legacy CJS with modern resolution: --module commonjs + --moduleResolution bundler (new in 6.0)

Important

--moduleResolution bundler resolves package.json "exports" conditions based on the output module syntax. With --module commonjs, imports always resolve with the "require" condition, not "import".

  • Correct use case: TypeScript emits CJS before a bundler resolves (e.g., Webpack ts-loader).
  • Incorrect use case: If your bundler resolves ESM imports first and then outputs CJS, use --module preserve or esnext instead.
  • .mts and .cts file extensions override --module -- a .mts file under --module commonjs still emits ESM and resolves with "import" conditions.

PR: #63084

A diagnostic-only flag to help compare TypeScript 6.0 output with TypeScript 7.0 output during migration. Not intended for long-term use.

When to use: Only when comparing .d.ts or error output between TypeScript 6.0 and 7.0 to isolate genuine differences from ordering noise.

Performance warning: Can add up to 25% slowdown to type-checking.

Background: TypeScript assigns internal type IDs in the order types are encountered. These IDs are used to sort union members. This means adding an unrelated declaration above a function can change the order of its inferred union return type in .d.ts output:

// Without the const: foo(): 100 | 500
// With the const:    foo(): 500 | 100  (500 gets a lower type ID from being processed first)
const x = 500;
export function foo(condition: boolean) {
    return condition ? 100 : 500;
}

TypeScript 7.0 uses parallel type checking, which makes the encounter order non-deterministic. To fix this, 7.0 sorts types by a content-based deterministic algorithm. --stableTypeOrdering makes 6.0 use the same algorithm, so you can compare outputs.

Source code

Source: src/compiler/commandLineParser.ts:978-987

{
    name: "stableTypeOrdering",
    type: "boolean",
    affectsSemanticDiagnostics: true,
    affectsBuildInfo: true,
    showInHelp: false,
    category: Diagnostics.Type_Checking,
    description: Diagnostics.Ensure_types_are_ordered_stably_and_deterministically_across_compilations,
    defaultValueDescription: false,
},

Note showInHelp: false -- this flag is intentionally hidden from tsc --help.

4.5 tsc with File Arguments When tsconfig.json Exists

PR: #62477 | Issue: #62197

Previously, running tsc foo.ts in a directory with a tsconfig.json silently ignored the config file. This was confusing. Now it's an error:

error TS5112: tsconfig.json is present but will not be loaded if files are specified
on commandline. Use '--ignoreConfig' to skip this error.

Migration: If you intentionally want to compile individual files without the tsconfig, use:

tsc --ignoreConfig foo.ts

This change was partly motivated by AI coding agents that run tsc foo.ts to "save time" -- because tsconfig was silently ignored, compilation used default settings, producing irrelevant errors that the agents would then try to "fix".

Source code

The new --ignoreConfig flag: src/compiler/commandLineParser.ts:691-699

{
    name: "ignoreConfig",
    type: "boolean",
    showInSimplifiedHelpView: true,
    category: Diagnostics.Command_line_Options,
    isCommandLineOnly: true,
    description: Diagnostics.Ignore_the_tsconfig_found_and_build_with_commandline_options_and_files,
    defaultValueDescription: false,
},

Error handling logic: src/compiler/executeCommandLine.ts:624-634

else if (!commandLine.options.ignoreConfig || commandLine.fileNames.length === 0) {
    const searchPath = normalizePath(sys.getCurrentDirectory());
    configFileName = findConfigFile(searchPath, fileName => sys.fileExists(fileName));
    if (commandLine.fileNames.length !== 0) {
        if (configFileName) {
            reportDiagnostic(createCompilerDiagnostic(
                Diagnostics.tsconfig_json_is_present_but_will_not_be_loaded_if_files_are_specified_on_commandline_Use_ignoreConfig_to_skip_this_error
            ));
            return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
        }
    }
}

4.6 dom.iterable and dom.asynciterable Merged into dom

PR: #62111 | Issue: #60959

Previously, using iteration methods on DOM collections (like NodeList) required "lib": ["dom", "dom.iterable"]. Now dom.iterable and dom.asynciterable are fully included in dom.

The old files are now empty stubs for backward compatibility. Specifying dom.iterable still works (it's just empty), so no changes are strictly required.

Migration: You can simplify your lib array:

  {
      "compilerOptions": {
-         "lib": ["dom", "dom.iterable", "es2020"]
+         "lib": ["dom", "es2020"]
      }
  }
  • The same merge also applies to WebWorker: webworker.iterable and webworker.asynciterable are now included in webworker.
  • dom now implicitly pulls in es2015 (for Symbol.iterator/Iterable) and es2018.asynciterable (for AsyncIterable).
Source code

src/lib/dom.iterable.generated.d.ts:

// This file's contents are now included in the main types file.
// The file has been left for backward compatibility.

5. New Standard Library Types

5.1 es2025 Target and Lib

PR: #63046 (by Kenta Moriuchi / petamoriken)

While there are no new JavaScript language features in ES2025, this target moves several declarations from esnext into es2025:

  • Promise.try (from es2025.promise)
  • Iterator helper methods (from es2025.iterator)
  • Set methods like union, intersection, difference (from es2025.collection)
  • Float16Array, Math.f16round, DataView.getFloat16/setFloat16 (from es2025.float16)
  • RegExp.escape (from es2025.regexp)
  • Intl.DurationFormat (from es2025.intl)
Lib reference chain

The esnext lib now references es2025 as its base at src/lib/esnext.d.ts:

/// <reference lib="es2025" />
/// <reference lib="esnext.intl" />
/// <reference lib="esnext.collection" />
/// <reference lib="esnext.decorators" />
/// <reference lib="esnext.disposable" />
/// <reference lib="esnext.array" />
/// <reference lib="esnext.error" />
/// <reference lib="esnext.sharedmemory" />
/// <reference lib="esnext.typedarrays" />
/// <reference lib="esnext.temporal" />
/// <reference lib="esnext.date" />

5.2 Temporal API Types

PR: #62628 (by Renegade334)

The TC39 Temporal proposal (stage 3) types are now included under esnext (or the granular esnext.temporal lib).

This file declares the Temporal namespace with all its types:

  • Temporal.Instant -- a point on the absolute timeline
  • Temporal.ZonedDateTime -- a date/time with timezone
  • Temporal.PlainDate, PlainTime, PlainDateTime -- civil date/time without timezone
  • Temporal.PlainYearMonth, PlainMonthDay -- partial date types
  • Temporal.Duration -- a length of time
  • Temporal.Now -- clock access

Usage:

// Requires --target esnext or "lib": ["esnext"]
let yesterday = Temporal.Now.instant().subtract({ hours: 24 });
let tomorrow = Temporal.Now.instant().add({ hours: 24 });

Runtime support (as of February 2026): Firefox 139+, Chrome 144+. See MDN browser compatibility for current status. No custom calendar support -- only built-in (non-Gregorian) calendars per latest TC39 spec.

Polyfill incompatibility: temporal-polyfill and @js-temporal/polyfill are NOT interassignable with these lib declarations. The types were written de novo and use different patterns than the polyfills.

5.3 Map.getOrInsert / Map.getOrInsertComputed

PR: #62612 (by Renegade334)

The ECMAScript "upsert" proposal (stage 4) adds two methods to Map and WeakMap.

interface Map<K, V> {
    getOrInsert(key: K, defaultValue: V): V;
    getOrInsertComputed(key: K, callback: (key: K) => V): V;
}

interface WeakMap<K extends WeakKey, V> {
    getOrInsert(key: K, defaultValue: V): V;
    getOrInsertComputed(key: K, callback: (key: K) => V): V;
}
  • getOrInsert(key, defaultValue) -- returns the existing value or inserts and returns defaultValue
  • getOrInsertComputed(key, callback) -- like getOrInsert but computes the default lazily via callback (useful for expensive defaults)

Usage:

// Before: tedious check-and-set pattern
let strictValue: unknown;
if (compilerOptions.has("strict")) {
    strictValue = compilerOptions.get("strict");
} else {
    strictValue = true;
    compilerOptions.set("strict", strictValue);
}

// After: one-liner
let strictValue = compilerOptions.getOrInsert("strict", true);

5.4 RegExp.escape

PR: #63046 (by Kenta Moriuchi / petamoriken)

The RegExp Escaping proposal (stage 4) adds RegExp.escape() for safely escaping special characters.

interface RegExpConstructor {
    escape(string: string): string;
}

Available in the es2025 lib (not just esnext).

Usage:

function matchWholeWord(word: string, text: string) {
    const escapedWord = RegExp.escape(word);
    const regex = new RegExp(`\\b${escapedWord}\\b`, "g");
    return text.match(regex);
}

6. Breaking Behavioral Changes

Beyond the explicit deprecations and new defaults, TypeScript 6.0 has several silent behavioral changes that can affect your code without producing a deprecation warning:

  • Type ordering in .d.ts output -- Union member ordering may differ between 6.0 and 7.0. Use --stableTypeOrdering to preview 7.0's ordering (see section 4.4).
  • Inference changes from this-less optimization -- Method-syntax functions that don't use this now participate in inference earlier, which can change type inference results in rare cases (see section 4.1).
  • Silent moduleResolution default shift -- Projects using --module commonjs without explicit moduleResolution now get bundler instead of node10 (see section 2.3). Projects using --module es2020 (or similar) without explicit moduleResolution now get bundler instead of classic (see section 2.5).
  • "use strict" always emitted -- Non-ESM output files now unconditionally include "use strict" (see section 2.8).
  • esModuleInterop emit changes -- Default import emit now uses __importDefault/__importStar helpers, changing runtime behavior for CJS interop (see section 2.7).

7. Migration Checklist

Priority 1: Likely Breaking for Most Projects

  • Set "types": ["node"] (or whatever @types packages you need) in tsconfig
  • Set "rootDir": "./src" if you were relying on inference and have source files in a subdirectory
  • Review the new strict: true default -- either embrace it or set "strict": false explicitly

Priority 2: Common Adjustments

  • Set explicit target if you need something other than es2025
  • Set explicit module if you need commonjs output
  • Remove baseUrl and inline its value into paths entries
  • Replace import * as x from "cjs-module" with import x from "cjs-module" (esModuleInterop always on)
  • Replace import ... assert { } with import ... with { }
  • Replace module Foo { } with namespace Foo { }
  • Update any scripts that run tsc with file arguments (now errors if tsconfig.json exists; use --ignoreConfig)
  • If you have side-effect imports that don't resolve, set "noUncheckedSideEffectImports": false
  • If you use @typescript/lib-* replacement packages, set "libReplacement": true

Priority 3: Deprecated Options to Remove

  • Remove downlevelIteration
  • Remove or update moduleResolution from node/node10/classic to nodenext/bundler
  • Remove or update module from amd/umd/system/none
  • Remove outFile and adopt a bundler
  • Remove alwaysStrict: false
  • Remove esModuleInterop: false
  • Remove allowSyntheticDefaultImports: false
  • Remove /// <reference no-default-lib="true"/>

Priority 4: Quick Wins

  • Simplify "lib": ["dom", "dom.iterable"] to "lib": ["dom"]
  • Consider adopting es2025 target to get RegExp.escape types
  • Try the new getOrInsert/getOrInsertComputed methods on Map

Temporary Escape Hatch

If you need to defer migration, add:

{
    "compilerOptions": {
        "ignoreDeprecations": "6.0"
    }
}

This silences all 6.0 deprecation warnings but will not work in TypeScript 7.0.

Automated Migration with ts5to6

The ts5to6 tool (by Andrew Branch, a TypeScript team member) automates the two most disruptive tsconfig migrations: baseUrl removal and rootDir inference. It works across monorepos, follows project references, and handles extends chains.

Install and run:

npx @andrewbranch/ts5to6 --fixBaseUrl .
npx @andrewbranch/ts5to6 --fixRootDir .

The argument is a path to a tsconfig.json or a directory containing one. Only one fix mode can be run at a time.

--fixBaseUrl (-b)

Removes baseUrl from your tsconfig(s) and rewrites paths entries to be relative to the tsconfig directory instead of relative to baseUrl. Handles these cases:

  • Non-relative paths like "components/*": ["components/*"] get rewritten to "components/*": ["./src/components/*"] (where ./src was the old baseUrl)
  • Wildcard catch-all "*": ["./src/*"] is added if any module resolution actually depended on baseUrl as a lookup root (detected by running the TypeScript compiler and checking for resolution failures)
  • extends in node_modules: If a base config in node_modules sets baseUrl, the tool sets "baseUrl": null in your config to clear the inherited value (since you can't edit node_modules)
  • Inherited paths: When paths are defined in a base config and baseUrl changes, the tool copies and transforms the path mappings into the local config

--fixRootDir (-r)

Sets an explicit rootDir matching what TypeScript 5.9 would have inferred, so your output directory structure stays the same. The tool:

  1. Creates a TypeScript program for each affected project
  2. Compares the old inferred root (common source directory) with the new default (tsconfig directory)
  3. If they differ, adds "rootDir": "./src" (or whatever the old value was) to the tsconfig
  4. Skips composite projects (they already had this behavior) and outFile projects

How it works under the hood

The tool uses a vendored, patched TypeScript compiler that emits special error signals when it detects baseUrl-dependent module resolution or rootDir inference mismatches. It discovers all tsconfigs in your workspace (by searching upward for package.json, then globbing for **/tsconfig*.json), recursively follows project references, and applies surgical JSON AST edits that preserve formatting, indentation, and trailing commas.


Appendix: All Referenced Pull Requests

PR Title Author
#62111 Merge dom.iterable and dom.asynciterable into dom TypeScript team
#62243 Less context-sensitivity on this-less functions Andarist
#62320 Allow --moduleResolution bundler with --module commonjs TypeScript team
#62338 Deprecate --moduleResolution node10 TypeScript team
#62418 Default rootDir to tsconfig.json directory TypeScript team
#62435 Deprecate no-default-lib directive TypeScript team
#62477 Error when tsc has file args with tsconfig present TypeScript team
#62509 Deprecate baseUrl TypeScript team
#62567 Deprecate esModuleInterop: false and allowSyntheticDefaultImports: false TypeScript team
#62612 Add getOrInsert/getOrInsertComputed types Renegade334
#62628 Add Temporal API types Renegade334
#62669 Deprecate module: amd/umd/system/none and moduleResolution: classic TypeScript team
#62844 Support subpath imports starting with #/ magic-akari
#62876 Deprecate legacy module keyword for namespaces TypeScript team
#62981 Deprecate outFile TypeScript team
#63046 Add es2025 target/lib with RegExp.escape petamoriken
#63054 Default types to [] TypeScript team
#63067 Deprecate target: es5 TypeScript team
#63071 Deprecate downlevelIteration TypeScript team
#63077 Deprecate asserts keyword on imports TypeScript team
#63084 Add --stableTypeOrdering flag TypeScript team
#63089 Deprecate alwaysStrict: false TypeScript team

Appendix: Referenced GitHub Issues

Issue Title
#60959 Merge dom.iterable into dom
#62194 Default rootDir to .
#62195 Default types to []
#62196 Deprecate target: es5
#62197 Error on tsc with files + tsconfig
#62199 Deprecate module: amd/umd/system
#62200 Deprecate moduleResolution: node10
#62206 Deprecate moduleResolution: classic
#62207 Deprecate baseUrl
#62209 Deprecate no-default-lib directive
#62210 Deprecate asserts on imports
#62211 Deprecate legacy module keyword
#62213 Deprecate alwaysStrict: false
#62529 Deprecate esModuleInterop: false
#54500 TypeScript 6.0/7.0 deprecation tracking

Resources

Resource Link
6.0 Beta announcement devblogs.microsoft.com/typescript/announcing-typescript-6-0-beta
6.0 Iteration Plan microsoft/TypeScript#63085
6.0 Maintenance Mode announcement microsoft/TypeScript#62963
LS bugs bulk-close explanation microsoft/TypeScript#62827
TypeScript Native Nightly (VS Code) marketplace.visualstudio.com
typescript-go repo github.com/microsoft/typescript-go
6.0/7.0 Deprecation Candidates microsoft/TypeScript#54500
Migration tool (ts5to6) github.com/andrewbranch/ts5to6
Migration info (aka.ms/ts6) aka.ms/ts6
TypeScript 7 native port progress devblogs.microsoft.com/.../progress-on-typescript-7-december-2025
Native preview package npmjs.com/package/@typescript/native-preview
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment