What new In Typescript 6.0, Exciting 7.0 Release Coming
Engineering8 min read
Idris SMarch 6, 2026

TypeScript 6.0 marks an important shift in TypeScript history; it is the last major release built on the existing JavaScript codebase. Microsoft is rewriting the entire TypeScript compiler and language service in Go, and TypeScript 6.0 serves as the bridge that leads us to the upcoming TypeScript 7.0, which promises near 10x faster build times.

But beyond the architectural shift, what matters most for everyday developers are the changes focused on best practices. Instead of requiring developers to opt into best practices, TypeScript now assumes them. The era of boilerplate tsconfig setup is ending.

In this article, we'll explore the most impactful changes and how you can start using them in your projects today.

Updated tsconfig.json Defaults

  • strict now true by default
  • module now defaults to esnext
  • target now defaults to the latest ECMAScript version
  • noUncheckedSideEffectImports now defaults to true
  • libReplacement now defaults false

Collectively, these updates signal a clear direction: TypeScript 6.0 assumes modern JavaScript, strict typing, and up-to-date runtimes by default, rather than requiring developers to opt in.

New Features in TypeScript 6.0

  1. 1.New Types for Temporal: Like most devs, you are probably tired of wrestling with JavaScript's Date class timezone headaches, mutable objects, and an API that never quite does what you expect. Temporal proposal aims to fix all of that, and it's now at Stage 3 of the TC39 process, meaning it's all but certain to land in JavaScript. TypeScript 6.0 is already ahead of the curve, shipping types for the Temporal API so you can start working with them today.
    // Current moment in time, like Date.now() but immutable const now = Temporal.Now.instant(); // Temporal.Instant // A calendar date with no time or timezone attached const date = Temporal.PlainDate.from('2026-03-04'); // Temporal.PlainDate
  2. 2.Less Context-Sensitivity on Functions: To understand why this change matters, we first need to understand how TypeScript infers types in generics In Methods vs Functions. Consider this example:
    type CallFunction = <T>(obj: { fn: (x: T) => void; value: T; }) => void; const callFunc: CallFunction = (obj) => { obj.fn(obj.value); }; // TypeScript infers T as string from the annotation callFunc({ fn: (name: string) => console.log(name.toUpperCase()), value: "TypeScript User" });

    Looking at this code, TypeScript has two simple jobs: infer the type of the argument passed as T, then use that type for x; because it knows arrow functions are stable.The problem occurs when the function is context-sensitive, meaning it uses method shorthand syntax with no explicit type annotation on its parameter. In that case, TypeScript can't accurately infer the type without risking circular reasoning: to type the function it needs T, but to know T it needs to type the function. To avoid going in circles, TypeScript skips context-sensitive functions and looks for other primitive clues first.

    // Method shorthand triggers context-sensitivity callFunc({ /* TypeScript sees method shorthand syntax and TypeScript thinks: "This might use 'this', skip it!" TypeScript skips fn entirely and looks for T elsewhere */ fn(name) { console.log(name.toUpperCase()); // 'name' is of type 'unknown' in older TypeScript }, // T is eventually inferred from value instead value: "TypeScript User" });

    Previously, TypeScript skipped method shorthand functions entirely when inferring types. In TypeScript 6.0, the compiler is smarter, it first checks whether the method actually uses `this`. If it doesn't, TypeScript treats it just like an arrow function and infers the type immediately instead of skipping it.

    // TypeScript 6.0 — method shorthand no longer skipped callFunc({ /*TypeScript checks: "Does fn use 'this'?" — No. So it treats it like an arrow function and infers T as string*/ fn(name) { console.log(name.toUpperCase()); // 'name' is now correctly inferred as string }, value: "TypeScript User" });

    The result: because `fn` doesn't use `this`, TypeScript no longer considers it context-sensitive. It infers `T` directly from `fn`'s parameter instead of skipping it and falling back to `value`.

  3. 3.RegExp.escape: Before TypeScript 6.0, if you wanted to use a string containing special regex characters like `.`, `*`, `+`, `?`, `^`, or `$` inside a Regular Expression, this usually dont work correctly, because these characters carry special meaning: like `.` means "any character" and `*` means "zero or more." If your string happened to contain any of them, your regex would silently break or behave unpredictably.
    const search = "$10.00"; const regex = new RegExp(search); // The regex thinks "$" is the "end of line" anchor // and "." is "any character". It won't find "$10.00" correctly!

    Instead of manually adding backslashes (e.g. `\$10\.00`) to every special character, `RegExp.escape` does it for you automatically treating it as text and not as a pattern.

    const search = "$10.00"; const safeSearch = RegExp.escape(search); // "\$10\.00" const regex = new RegExp(safeSearch); console.log(regex.test("$10.00")); // true
  4. 4.The dom lib Now Contains dom.iterable and dom.asynciterable: Before TypeScript 6.0, the Web API types (the "DOM") were split into three separate pieces in TypeScript: `dom`, `dom.iterable`, and `dom.asynciterable`. Because many older browsers didn't support iteration, TypeScript forced you to explicitly add `dom.iterable` to your config if you wanted to loop over DOM elements. Your `tsconfig.json`
    { "compilerOptions": { "lib": ["dom", "dom.iterable", "esnext"] } }

    Since almost all modern web development environments support iteration, there's no reason to keep them separate. In TypeScript 6.0, `dom.iterable` and `dom.asynciterable` have been merged directly into the main `dom` library. You can now just write `"dom"` and get everything automatically:

    { "compilerOptions": { "lib": ["dom", "esnext"] } } // For...of on NodeList works without any extra config for (const el of document.querySelectorAll('div')) { console.log(el.textContent); } // for await...of on ReadableStream also works out of the box async function readStream(stream: ReadableStream<string>) { for await (const chunk of stream) { console.log(chunk); } }

Breaking Changes & Default Adjustments

FeatureOld BehaviorNew Behavior in 6.0
rootDir DefaultVaried based on file structure.Now defaults to . (the current directory).
types DefaultIncluded all @types packages found.Now defaults to [] (empty) to improve performance and prevent global "pollution".
Command-Line FilesYou could list files AND use a tsconfig.This is now an Error. You must use one or the other.
DOM Librariesdom.iterable and dom.asynciterable were separate.They are now fully included in the main dom library.

Deprecations in 6.0

FeatureReplacementReason for Removal
target: es5Upgrade to es2015 or later.ES5 is extremely old; most tools handle downleveling better than TS.
--downlevelIterationUse a modern target or external transpiler.Part of the ES5 deprecation path.
module: amd, umd, systemjsUse esnext or commonjs.These formats are largely obsolete for modern development.
moduleResolution: nodeUse node16, nodenext, or bundler."Node10" (legacy) resolution is often inaccurate for modern packages.
--baseUrlUse paths or Node's subpath imports.Causes confusion with relative vs. absolute imports.
--outFileUse an external bundler (esbuild, Vite, etc.).Complex to maintain; external tools are much faster and better at this.
module Foo { ... }Change to namespace Foo { ... }.Avoids conflict with the upcoming "ECMAScript Modules" proposal.
asserts { type: "json" }Change to with { type: "json" }.The JS spec changed from asserts to with (Import Attributes).
--alwaysStrict: falseAlways use strict mode.Modern JavaScript and modules are strict by default.

Migrating to TypeScript 6.0

Upgrading to TypeScript 6.0 is straightforward, simply install the Release Candidate (RC) or the latest stable 6.0 version, use:

npm install -D typescript@rc # OR specifically npm install -D typescript@6.0.1-rc

Now Review the following checklist to clean up your config and prepare for TypeScript 7.0:

  1. Clean Up Tsconfig: Since TypeScript 6.0 is a "bridge" to the native Go-based version 7.0, you should follow these manual steps to fix the most common deprecation warnings:
    • Update tsconfig.json lib: You no longer need to split the DOM iterables switch to Es2025 that gives you access to RegExp.escape and Temporal
      { "compilerOptions": { "lib": ["dom", "es2025", "esnext"] } }
    • Fix Import Attributes: If you imported JSON or other assets, using the asserts keyword is now an error. Replace it with with see example below
      // Before 6.0 import data from "./file.json" asserts { type: "json" }; // In TypeScript 6.0 and later import data from "./file.json" with { type: "json" };
    • Replace Namespaces: If you still use module declarations, switch them to namespace.  you should use a find and replace feature on your IDE to update them
      // Before 6.0 module MyNamespace { ... }; // In TypeScript 6.0 and later namespace MyNamespace { ... };
  2. 7.0 prep: I like think of TypeScript 6.0 as compatibility check although there are not a tone of new features, bu by upgrading to 6.0 and fixing the deprecation warnings, you are ensuring your project is ready to reap the massive performance benefits of the native Go-based compiler the moment TypeScript 7.0 launches.
Share