TypeScript release

TypeScript 4.6 for JavaScript users

  • Released 28 February 2022
  • Examples run with TypeScript 5.9

TypeScript 4.6 was announced on 28 February 2022. It changed something for every JavaScript file an editor opens, checked or not: TypeScript now reports JavaScript syntax and binding errors, such as a const declared twice, in .js files without checkJs or // @ts-check.

For checked files the release adds narrowing that plain JavaScript benefits from: destructured parts of a discriminated union stay linked, and parameters typed by a union of tuples narrow each other.

At a glance

ReleaseTypeScript 4.6
Released28 February 2022, the day of its announcement on the TypeScript blog
SourceTypeScript 4.6 release notes
ExamplesEvery example runs through TypeScript 5.9.3 when this site is built.
Previous releaseTypeScript 4.5
Next releaseTypeScript 4.7

What changed for JavaScript

Syntax and binding errors in every JavaScript file

Before 4.6, an unchecked .js file got almost no errors. Now TypeScript reports JavaScript's own syntax and binding errors there too: a block-scoped name declared twice (TS2451), a modifier where JavaScript does not allow one, and the like. They show up in editors that use TypeScript's language service and when tsc reads a JavaScript file. Type errors still need checkJs.

The release notes give one way to silence them in a file: // @ts-nocheck at the top. This site's tests add a second with TypeScript 5.9: the errors appear only when checkJs is left out of the config. An unchecked file with a duplicate const gets TS2451 then, and nothing with "checkJs": false or with // @ts-nocheck.

Destructured discriminated unions

When kind and payload are destructured from a discriminated union into const bindings (or parameters that are never reassigned), checking kind now narrows payload too.

actions.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/**
 * @typedef {{ kind: "count", payload: number } | { kind: "label", payload: string }} Action
 */

/** @param {Action} action */
export function describe(action) {
  const { kind, payload } = action;
  if (kind === "count") {
    return payload.toFixed(0);
  }
  return payload.toUpperCase();
}
Destructured kind and payload stay linked.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": [
    "*.js"
  ]
}

Parameters that depend on each other

A function typed with a rest parameter that is a union of tuples, (...args: ["count", number] | ["label", string]) => string, narrows its second parameter when you check the first. In JavaScript, put the function type in a @type tag on the variable that holds the function.

events.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
/** @type {(...args: ["count", number] | ["label", string]) => string} */
export const format = (kind, value) => {
  if (kind === "count") {
    return value.toFixed(0);
  }
  return value.toUpperCase();
};

format("count", 3);
format("label", "sale");
Parameters typed by a union of tuples narrow each other.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": [
    "*.js"
  ]
}

Mismatched @param names in TypeScript files

In a checked .js file a @param name that matches no parameter was already an error (TS8024). 4.6 adds an editor suggestion for the same mistake in .ts files, where JSDoc carries no types.

cart.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. cart.js(2,21): error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name. cart.js(4,24): error TS7006: Parameter 'quantity' implicitly has an 'any' type. checked 21 October 2026
/** @param {number} qty */error TS8024: JSDoc '@param' tag has name 'qty', but there is no parameter with that name.
export function double(quantity) {error TS7006: Parameter 'quantity' implicitly has an 'any' type.
  return quantity * 2;
}
A @param name that matches no parameter.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

target es2022

The es2022 target and lib bring Array.prototype.at(), Object.hasOwn and the cause option of Error.

Code before super()

A subclass with field initializers may now run code before super() in its constructor, as long as that code does not touch this; before 4.6 any code there was an error.

What did not change

Type checking in .js files is still opt-in: without checkJs or // @ts-check, the new errors are JavaScript errors, not type errors.

Upgrade notes

Two breaking changes in the release notes:

  • Unchecked JavaScript files now show syntax and binding errors; add // @ts-nocheck to a file you do not want TypeScript to report anything in, or set "checkJs": false for the whole project.
  • An object rest on a generic value now drops methods and other members a spread would not copy.

Gotchas

  • // @ts-nocheck turns off everything TypeScript reports in that file, the new JavaScript errors included, so use it on files you cannot change rather than to hide one error.

Sources

Last reviewed 20 October 2026.