At a glance
Last verified 21 October 2026 with TypeScript 5.9.3; the 6.0 and 7.0 results come from one run each of 6.0.3 and 7.0.2 over this site's 484 example projects on 20 October 2026.
| Compared | TypeScript 5.9 | TypeScript 6.0 | TypeScript 7.0 |
|---|---|---|---|
| Released | 1 August 2025 | 23 March 2026 | 8 July 2026 |
| Written in | TypeScript, run on Node.js | TypeScript, run on Node.js (the last such release) | Go: a native tsc |
strict by default | Off | On | On |
types by default | Every @types package | []: none unless listed | [] |
module and target by default | commonjs and es5 | esnext and the newest ECMAScript year | As 6.0 |
baseUrl, moduleResolution: node, target: es5 | Accepted | Deprecated (TS5101, TS5107) | Removed (TS5102, TS5108) |
@enum, @class functions, Closure function types, a value as a type | Read | Read | Not read |
| This site's 484 example projects | The baseline | 474 identical, 10 differ (defaults and deprecations) | 460 identical, 24 differ (10 defaults, 14 JavaScript changes) |
| Speed, per the 7.0 announcement | Not compared | The baseline | Full builds 8 to 12 times faster than 6.0 |
| Programmatic API (for linters and other tools) | Yes | Yes, as in 5.9 | None yet; 7.1 is meant to bring one |
Three releases, one direction
TypeScript 5.9 is the version this site checks every example with. 6.0 is the last release written in TypeScript: it changes several defaults and deprecates old options, and otherwise behaves like 5.9. 7.0 is the native port, rewritten in Go and run as the same tsc from the same typescript package; it keeps 6.0’s defaults, removes what 6.0 deprecated, and reads JavaScript files more like TypeScript files. The release pages cover each in detail: 5.9, 6.0, 7.0.
What the one-off runs showed
On 20 October 2026 we ran TypeScript 6.0.3 and 7.0.2 over the 484 example projects this site checked at the time, and compared each project’s errors with what 5.9.3 reports:
- 6.0.3: 474 projects reported exactly the same errors. The 10 that differed each set, or left out, an option whose default changed or that 6.0 deprecates.
- 7.0.2: 460 identical. Of the 24 that differed, 10 differ for the same reasons as under 6.0, and 14 because of 7.0’s JavaScript changes:
@enum,@classand@constructorfunctions, Closure function types, a value used as a type,argumentsno longer allowing extra arguments,@privatein a constructor function, and three errors reported with a different code or not at all.
Those were one-off runs in a scratch folder, not part of this site’s build; the examples added since then have not been run under 6.0 or 7.0.
What 7.0 stops reading
Four JSDoc patterns are behind most of the differences. Each has a replacement that passes in 5.9, 6.0 and 7.0 alike, so the rewrite can happen before the upgrade.
@enum
@enum is an ordinary tag in 7.0. This example passes in 5.9 and, in our run, failed under 7.0.2 with TS2749:
/** @enum {string} */
export const Status = {
Draft: "draft",
Live: "live",
Archived: "archived",
};
/**
* @param {Status} status
* @returns {boolean}
*/
export function isVisible(status) {
return status === Status.Live;
}
isVisible(Status.Draft);jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} The replacement is a const object and a union of its values, which also checks the values more tightly in every version:
export const Status = /** @type {const} */ ({
Draft: "draft",
Live: "live",
});
/** @typedef {(typeof Status)[keyof typeof Status]} StatusValue */
/** @param {StatusValue} status */
export function setStatus(status) {
return status;
}
setStatus(Status.Live);
setStatus("deleted");error TS2345: Argument of type '"deleted"' is not assignable to parameter of type 'StatusValue'.export const Status = {
Draft: "draft",
Live: "live",
} as const;
type StatusValue = (typeof Status)[keyof typeof Status];
export function setStatus(status: StatusValue) {
return status;
}
setStatus(Status.Live);
setStatus("deleted");error TS2345: Argument of type '"deleted"' is not assignable to parameter of type 'StatusValue'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Closure function types
7.0 does not parse {function(string): number} (TS1005 in our run). Arrow syntax works everywhere:
/** @typedef {{ sku: string, price: number }} Product */
/** @type {(amount: number, currency?: string) => string} */
export const formatPrice = (amount, currency = "USD") =>
new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount);
/**
* @param {Product[]} products
* @param {(a: Product, b: Product) => number} compare
*/
export function sorted(products, compare) {
return [...products].sort(compare);
}
sorted([{ sku: "TEE-01", price: 19.5 }], (a, b) => a.price - b.price);
formatPrice(19.5);type Product = { sku: string; price: number };
export const formatPrice: (amount: number, currency?: string) => string = (amount, currency = "USD") =>
new Intl.NumberFormat("en-US", { style: "currency", currency }).format(amount);
export function sorted(products: Product[], compare: (a: Product, b: Product) => number) {
return [...products].sort(compare);
}
sorted([{ sku: "TEE-01", price: 19.5 }], (a, b) => a.price - b.price);
formatPrice(19.5);jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} Constructor functions
Functions marked with @class or @constructor are no longer read as classes (TS2683 and TS7009 in our run). Write a class; the @class page shows both.
A value’s name as a type
{defaults} meaning typeof defaults is TS2749 under 7.0. Write typeof, as the ReturnType page does.
Speed
The 7.0 announcement reports full builds 8 to 12 times faster than 6.0, through native code and checking files in parallel (the experimental --checkers option sets how many type-checking threads run). We did not benchmark it; the figure is the announcement’s. For a JavaScript project the gain shows up as a faster npm run lint and quicker errors in the editor.
The tools question
7.0 ships without a programmatic API, which 7.1 is meant to bring. Tools that call TypeScript as a library, typescript-eslint among them, and editor support for Vue, Svelte, Astro and MDX files, still need 6.0, which the TypeScript team publishes as @typescript/typescript6 (with a tsc6 command) so that both can be installed. This site’s own examples gate is one such tool, which is why it still runs 5.9.
An upgrade path
- Write down your defaults on 5.9. Set
strict,types,moduleandtargetexplicitly injsconfig.json, so the defaults that matter most do not move under you; the 6.0 page lists every default that changes. - Move to 6.0 and fix every deprecation error, rather than silencing them with
"ignoreDeprecations": "6.0": the common ones in JavaScript projects arebaseUrlandmoduleResolution: "node". - Turn on
stableTypeOrderingin 6.0 to see 7.0’s type ordering, which matters most if you publish.d.tsfiles written from JSDoc. - Rewrite the four JSDoc patterns above. The replacements pass in 5.9 and 6.0 already, so this can happen before any upgrade.
- Try 7.0 beside 6.0 with
npx -p typescript@7 tsc -p jsconfig.json, and switch when it reports what 6.0 reports. Keep 6.0 installed for tools that need its API.
Which to choose
Choose TypeScript 5.9 when…
- Your tools call TypeScript as a library and have not moved on, and you are not ready to set the 6.0 defaults explicitly.
- You want the version this site's examples are checked with today.
Choose TypeScript 6.0 when…
- You are on the way to 7.0: it reports every option 7.0 removes, while still running your tools.
- You need the old JSDoc forms (
@enum, constructor functions) for a while longer, with the new defaults.
Choose TypeScript 7.0 when…
- Checking time matters: a large codebase, an editor that lags, a slow CI step.
- Your JSDoc already uses the forms 7.0 reads (
typeof, union@typedefs,class, arrow function types), and no tool you rely on needs the API.
Questions
Do I have to rewrite my JSDoc for TypeScript 7.0?
Only the older forms: @enum, @class constructor functions, Closure function types such as function(string): number, and a value's name used as a type. Each has a replacement that already works in 5.9, so you can rewrite before upgrading.
Does a jsconfig.json still work in 6.0 and 7.0?
Yes. In our one-off runs, a jsconfig.json kept its file-name defaults under both. It also got the new defaults (strict on, types: []), so a config that relied on the old ones reported errors 5.9 did not. Setting strict and types explicitly avoids that.
Why does this site still check with 5.9?
The examples gate uses TypeScript's programmatic API, which 7.0 does not have yet. Moving the pin is planned; until then, pages note where 6.0 or 7.0 behaves differently, based on the release notes and the one-off runs.
Sources
- Announcing TypeScript 7.0 · TypeScript blog
- TypeScript 6.0 release notes · TypeScript handbook
- CHANGES.md: changes between TypeScript 6 and the native port · microsoft/typescript-go on GitHub
- TypeScript 5.9 release notes · TypeScript handbook
Last reviewed 21 October 2026.