Home / Articles / TypeScript 6 and 7: Smarter Inference, Then a Go-Based Rewrite

This article is published in English.

TypeScript 6 and 7: Smarter Inference, Then a Go-Based Rewrite

Learn how TypeScript 6 fixed key inference gaps and modernized defaults, setting the stage for TypeScript 7's ground-up compiler rewrite in Go.

1255 words

TypeScript has been improving on two separate fronts recently, and together they tell one story: the language is getting both smarter and faster. TypeScript 6, shipped as the final release written in the traditional JavaScript-based compiler before the big architectural shift, focused on fixing long-standing inference quirks and modernizing defaults. TypeScript 7 then took the more radical step of rewriting the compiler itself in Go, chasing raw speed rather than new syntax. Looking at both together shows how the toolchain arrived at its current state — first getting more accurate, then getting dramatically quicker.

Smarter Inference in TypeScript 6

Anyone who has typed out a method shorthand and then watched the parameter quietly collapse into any knows how frustrating TypeScript's old inference rules could be. TypeScript 6 tackles that problem along with a handful of other inference gaps that have sent developers searching for answers for years.

Previously, any function that referenced this internally was treated as "contextually sensitive," which meant the compiler skipped parameter-type inference for it entirely — even in cases where this was never actually used inside the function body:

// Old behavior: 'user' silently became 'any'
const handlers = {
  onSave(user) {
    console.log(user.name); // no autocomplete, no error
  },
};

With TypeScript 6, the compiler only treats a function as contextually sensitive when this is genuinely used inside it. If it isn't, normal inference kicks back in and the parameter gets its expected type instead of falling back to any:

// TypeScript 6: 'user' is correctly inferred from context
const handlers: Handlers = {
  onSave(user) {
    console.log(user.name); // fully typed
  },
};

It looks like a small technical adjustment, but it has an outsized effect on daily development, especially in React and Next.js codebases where object methods and event handlers are everywhere.

TypeScript 6 also brings first-class support for using declarations, which formalize explicit resource management. Instead of manually wrapping cleanup logic in a try/finally block, you can let the compiler handle disposal automatically once a value goes out of scope:

function readConfig() {
  using file = openFile("./config.json"); // auto-disposed at scope end
  return JSON.parse(file.read());
}

Subpath imports get cleaner too. The #/ prefix now works through the imports field, letting you avoid long chains of relative ../../../ paths:

{
  "imports": {
    "#/*": "./src/*"
  }
}
import { formatCurrency } from "#/utils/currency";
// instead of: import { formatCurrency } from "../../../utils/currency";

Several defaults changed as well. The target option now defaults to ES2023 instead of the ancient ES3 baseline, module defaults to ESNext, and moduleResolution defaults to bundler. The types option also defaults to an empty array, which stops TypeScript from automatically scanning and loading every @types package it can find. That last change alone is credited with build-time improvements in the range of 20 to 50 percent, according to Microsoft, which makes reviewing your tsconfig.json worthwhile even if you have no interest in adopting any new language features.

Taken together, the TypeScript 6 recommendations are: audit any method-heavy objects in your codebase, since they may get automatic type-safety improvements for free; reach for using wherever you deal with files, connections, or timers that need cleanup; don't just inherit the new compiler defaults silently — set them explicitly in tsconfig.json so your intent is clear; and expect the type definitions shipped by frameworks and libraries like React, Redux, and Tailwind tooling to catch up with these changes over the following weeks. TypeScript 6 isn't a stopgap release — it noticeably reduces the number of inference surprises you run into day to day, which by itself is a good enough reason to upgrade.

The Ground-Up Rewrite in TypeScript 7

Where TypeScript 6 refined how the compiler reasons about types, TypeScript 7 goes after something more fundamental: how fast the whole toolchain runs. Microsoft rewrote the compiler, the language service, and the surrounding tooling entirely in Go, replacing the self-hosted JavaScript implementation that had powered TypeScript for years. This is not a minor version bump — it's described as the largest performance change in the language's history.

Anyone who has stared at an editor's loading spinner while waiting for a type error to surface will recognize the exact pain this rewrite targets.

Because the team mapped over the original compiler logic instead of rebuilding the type-checking rules from scratch, compatibility with existing code stayed largely intact throughout the transition.

Microsoft's own published benchmarks give a sense of the scale of the improvement. On the roughly 1.5-million-line VS Code codebase, a full build that used to take about 125 seconds now finishes in around 10 seconds. The time to see the first type error in the editor dropped from about 17 seconds to under 1.5 seconds. Memory usage fell by roughly 18 percent, and crashes in the language server dropped by more than 60 percent. These aren't purely synthetic numbers either — companies including Slack, Figma, Google, Notion, and Vercel tried the new compiler on real production projects before it shipped, and reported that the gains held up outside of controlled benchmarks.

For teams working with React and Next.js, this translates into concrete everyday benefits. In a large monorepo, waiting on tsc to catch a type mismatch could previously take several seconds; that overhead shrinks dramatically under the Go-based compiler:

// Before: waiting on tsc to catch this in a large monorepo could take seconds
interface UserCardProps {
  name: string;
  avatarUrl?: string;
  onSelect: (userId: string) => void;
}

function UserCard({ name, avatarUrl, onSelect }: UserCardProps) {
  // With TS7's native checker, this feedback loop is nearly instant
  return (
    <button onClick={() => onSelect(name)} className="rounded-lg p-2 hover:bg-slate-100">
      {avatarUrl && <img src={avatarUrl} alt={name} className="h-8 w-8 rounded-full" />}
      <span>{name}</span>
    </button>
  );
}

Large Next.js applications with hundreds of components no longer treat type-checking as the CI bottleneck it used to be. Projects built with heavy generic types, such as those combining Tailwind and Redux, get noticeably faster incremental builds. Editor autocomplete in big monorepos also feels much more responsive.

Before upgrading, there are a few caveats worth flagging. Strict mode is now the default, so previously loose codebases may surface new errors. Legacy compilation targets like es5, along with older module-resolution settings, are no longer just warnings — they are treated as hard errors. And because the programmatic API is only partially stable in this release, any framework or tool that depends on it directly should hold off until TypeScript 7.1 before upgrading.

None of this involves new syntax or fundamentally different grammar — TypeScript 7 exists mainly to answer the decade-old complaint about compiler performance. If your team runs a large React or Next.js codebase, this is the release that finally makes tsc feel less like something you're fighting against. As with any major infrastructure change, it's worth trying on a side branch first; your CI pipeline will thank you for the caution.