Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
34d48bc
Add TypeScript 7 support to dtslint
jakebailey Aug 17, 2026
09d50d3
Add TypeScript 7.0 to dtslint
jakebailey Aug 17, 2026
79e8e4a
Update TypeScript 7 changeset
jakebailey Aug 17, 2026
fb43d70
Run ESLint rules for TypeScript 7
jakebailey Aug 17, 2026
d9d8623
Remove accidental next alias
jakebailey Aug 17, 2026
4c90961
Load TypeScript 7 with require
jakebailey Aug 17, 2026
e5eff86
Upgrade repository to TypeScript 6
jakebailey Aug 17, 2026
8448851
Match legacy diagnostic scoping for TypeScript 7
jakebailey Aug 17, 2026
bdce61d
Ignore intentional dtslint fixture in knip
jakebailey Aug 17, 2026
ae91019
Make TypeScript 7 ESLint fixture CI-safe
jakebailey Aug 17, 2026
1809b1b
Normalize TypeScript 7 type member order
jakebailey Aug 17, 2026
2d8c7a6
Test TypeScript 7 expect-error ranges
jakebailey Aug 17, 2026
4c29c4e
Address TypeScript 7 review feedback
jakebailey Aug 18, 2026
782b182
Share expect-error range evaluation
jakebailey Aug 18, 2026
f7d0558
Allow TS7 ESLint test more time on Windows
jakebailey Aug 18, 2026
31768ae
Discover local TypeScript executables
jakebailey Aug 18, 2026
dc659a2
Parse expect-error block comment ranges
jakebailey Aug 18, 2026
9102d9e
Require an explicit local TypeScript 7 executable
jakebailey Aug 18, 2026
766e2a3
Parse expect-error ranges without backtracking
jakebailey Aug 18, 2026
9f87962
Load local TypeScript 7 packages coherently
jakebailey Aug 18, 2026
81fe324
Use Corsa terminology for TypeScript 7
jakebailey Aug 21, 2026
51009ec
Clean up TypeScript changesets
jakebailey Aug 21, 2026
0e4276f
Fold version ranges into Corsa changeset
jakebailey Aug 21, 2026
b17027d
Use shipped Corsa API types
jakebailey Aug 21, 2026
9e8d52c
Fix lockfile after rebase
jakebailey Sep 16, 2026
edd5a04
Update TypeScript 7.1 prerelease
jakebailey Sep 17, 2026
2b75887
Use latest Corsa parsing APIs
jakebailey Sep 18, 2026
929a4aa
Support stable Corsa entrypoints
jakebailey Sep 18, 2026
9462595
Update TypeScript 7.1 nightly
jakebailey Sep 21, 2026
1581882
Update TypeScript 7.1 nightly API
jakebailey Sep 26, 2026
42851df
Gate TypeScript next in regular runs
jakebailey Sep 28, 2026
7075b99
Compare TypeScript versions by declared order
jakebailey Sep 28, 2026
f16edc2
Allow Corsa test startup on Windows
jakebailey Sep 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/strong-dragons-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@definitelytyped/dtslint": patch
"@definitelytyped/eslint-plugin": patch
"@definitelytyped/typescript-packages": patch
"@definitelytyped/typescript-versions": patch
"@definitelytyped/utils": patch
---

Add TypeScript 7.0 and 7.1 support through the Corsa compiler API, including compiler diagnostics, `$ExpectType`
assertions, version-ranged `@ts-expect-error` directives, multi-project failure reporting, and local TypeScript packages.
8 changes: 8 additions & 0 deletions .changeset/tidy-tigers-compile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@definitelytyped/dts-critic": patch
"@definitelytyped/dtslint": patch
"@definitelytyped/eslint-plugin": patch
"dts-gen": patch
---

Upgrade bundled TypeScript dependencies to 6.0 and update TypeScript ESLint dependencies for compatibility.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
"@types/jest": "^30.0.0",
"@types/node": "^25.3.3",
"@types/yargs": "^17.0.35",
"@typescript-eslint/eslint-plugin": "^8.56.1",
"@typescript-eslint/parser": "^8.56.1",
"@typescript-eslint/eslint-plugin": "^8.67.0",
"@typescript-eslint/parser": "^8.67.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jsdoc": "^48.11.0",
"jest": "^30.2.0",
"knip": "^5.85.0",
"prettier": "^3.8.1",
"ts-jest": "^29.4.6",
"typescript": "^5.9.3"
"ts-jest": "^29.4.12",
"typescript": "^6.0.3"
},
"pnpm": {
"overrides": {
Expand Down
2 changes: 1 addition & 1 deletion packages/definitions-parser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
},
"devDependencies": {
"@types/pacote": "^11.1.8",
"typescript": "^5.9.3"
"typescript": "^6.0.3"
},
"peerDependencies": {
"typescript": "<7"
Expand Down
3 changes: 1 addition & 2 deletions packages/dts-critic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@
},
"dependencies": {
"@definitelytyped/header-parser": "workspace:*",
"typescript": "^5.9.3",
"typescript": "^6.0.3",
"yargs": "^17.7.2"
},
"peerDependencies": {
"typescript": "<7"
},
"devDependencies": {},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/dts-gen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
},
"dependencies": {
"dts-dom": "^3.7.0",
"typescript": "^5.9.3",
"typescript": "^6.0.3",
"which": "^6.0.1",
"yargs": "^17.7.2"
},
Expand Down
7 changes: 7 additions & 0 deletions packages/dtslint/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,13 @@ Use your locally installed version of TypeScript.
```sh
dtslint --localTs node_modules/typescript/lib types
```

For TypeScript 7, pass the TypeScript package directory after building both the native compiler and JavaScript API:

```sh
dtslint --localTs ../TypeScript/packages/typescript types
```

- `--expectOnly`

Disable all the lint rules except the one that checks for type correctness.
Expand Down
18 changes: 8 additions & 10 deletions packages/dtslint/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,21 @@
"@definitelytyped/typescript-packages": "workspace:*",
"@definitelytyped/typescript-versions": "workspace:*",
"@definitelytyped/utils": "workspace:*",
"@typescript-eslint/eslint-plugin": "^8.56.1",
"@typescript-eslint/parser": "^8.56.1",
"@typescript-eslint/types": "^8.56.1",
"@typescript-eslint/typescript-estree": "^8.56.1",
"@typescript-eslint/utils": "^8.56.1",
"@typescript-eslint/eslint-plugin": "^8.67.0",
"@typescript-eslint/parser": "^8.67.0",
"@typescript-eslint/types": "^8.67.0",
"@typescript-eslint/typescript-estree": "^8.67.0",
"@typescript-eslint/utils": "^8.67.0",
"eslint": "^8.57.1",
"eslint-plugin-import": "^2.32.0",
"semver": "^7.7.4",
"strip-json-comments": "^3.1.1"
},
"peerDependencies": {
"typescript": "<7"
"strip-json-comments": "^3.1.1",
"typescript": "^6.0.3"
},
"devDependencies": {
"@types/eslint": "^8.56.12",
"@types/semver": "^7.7.1",
"typescript": "^5.9.3"
"typescript-7.1": "npm:typescript@~7.1.0-0"
},
"engines": {
"node": ">=20.17.0"
Expand Down
80 changes: 59 additions & 21 deletions packages/dtslint/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ import { TsVersion, lint } from "./lint";
import { getCompilerOptions, packageDirectoryNameWithVersionFromPath, packageNameFromPath } from "./util";
import assert = require("assert");

// TODO: Enable once the TypeScript 7.1 API is stable enough for regular Definitely Typed runs.
const testTypeScriptNextByDefault = false;
const latestTypeScriptVersionToTest: TypeScriptVersion = testTypeScriptNextByDefault
? TypeScriptVersion.latest
: TypeScriptVersion.shipped[TypeScriptVersion.shipped.length - 1];

async function main(): Promise<void> {
const args = process.argv.slice(2);
let dirPath = process.cwd();
Expand Down Expand Up @@ -91,6 +97,9 @@ async function main(): Promise<void> {
if (onlyNpmChecks && skipNpmChecks) {
throw new Error("Cannot use --onlyNpmChecks and --skipNpmChecks together.");
}
if (onlyTestTsNext && tsLocal) {
throw new Error("Cannot use --onlyTestTsNext and --localTs together.");
}
if (lookingForTsLocal) {
throw new Error("Path for --localTs was not provided.");
}
Expand Down Expand Up @@ -208,26 +217,26 @@ async function runTests(
// associated ts3.2, ts3.5, ts3.6 directories, for
// <=3.2, <=3.5, <=3.6 respectively; the root level is for 3.7 and above.
// so this code needs to generate ranges [lowest-3.2, 3.3-3.5, 3.6-3.6, 3.7-latest]
const supportedTypesVersions = typesVersions.filter(TypeScriptVersion.isSupported);
if (supportedTypesVersions.length !== typesVersions.length) {
const unsupportedTypesVersions = typesVersions.filter((v) => !TypeScriptVersion.isSupported(v));
const unsupportedTypesVersions = typesVersions.filter(
(version) => TypeScriptVersion.compare(version, TypeScriptVersion.lowest) < 0,
);
if (unsupportedTypesVersions.length) {
warnings.push(
`Package ${packageName} has unsupported TypeScript versions that will not be tested: ${unsupportedTypesVersions.join(", ")}`,
);
}
const lows = [TypeScriptVersion.lowest, ...supportedTypesVersions.map(next)];
const his = [...supportedTypesVersions, TypeScriptVersion.latest];
assert.strictEqual(lows.length, his.length);
for (let i = 0; i < lows.length; i++) {
const low = maxVersion(minVersion, lows[i]);
const hi = his[i];
for (const range of getTypeScriptTestRanges(typesVersions)) {
const low = maxVersion(minVersion, range.low);
const hi = range.high;
assert(
parseFloat(hi) >= parseFloat(low),
`'"minimumTypeScriptVersion": "${minVersion}"' in package.json skips ts${hi} folder.`,
TypeScriptVersion.compare(hi, low) >= 0,
`'"minimumTypeScriptVersion": "${minVersion}"' in package.json skips ${
range.directoryVersion ? `ts${range.directoryVersion} folder` : "the root definition"
}.`,
);
const isLatest = hi === TypeScriptVersion.latest;
const versionPath = isLatest ? dirPath : joinPaths(dirPath, `ts${hi}`);
if (lows.length > 1) {
const isLatest = range.directoryVersion === undefined;
const versionPath = isLatest ? dirPath : joinPaths(dirPath, `ts${range.directoryVersion}`);
if (typesVersions.length > 0) {
console.log("testing from", low, "to", hi, "in", versionPath);
}
const testTypesResult = await testTypesVersion(
Expand Down Expand Up @@ -268,14 +277,43 @@ function combineErrorsAndWarnings(errors: string[], warnings: string[]): Error |

function maxVersion(v1: AllTypeScriptVersion, v2: TypeScriptVersion): TypeScriptVersion {
// Note: For v1 to be later than v2, it must be a current Typescript version. So the type assertion is safe.
return parseFloat(v1) >= parseFloat(v2) ? (v1 as TypeScriptVersion) : v2;
return TypeScriptVersion.compare(v1, v2) >= 0 ? (v1 as TypeScriptVersion) : v2;
}

function next(v: TypeScriptVersion): TypeScriptVersion {
const index = TypeScriptVersion.supported.indexOf(v);
assert.notStrictEqual(index, -1);
assert(index < TypeScriptVersion.supported.length);
return TypeScriptVersion.supported[index + 1];
export function getTypeScriptTestRanges(typesVersions: readonly AllTypeScriptVersion[]): readonly {
low: TypeScriptVersion;
high: TypeScriptVersion;
directoryVersion?: AllTypeScriptVersion;
}[] {
const ranges: {
low: TypeScriptVersion;
high: TypeScriptVersion;
directoryVersion?: AllTypeScriptVersion;
}[] = [];
let low: TypeScriptVersion = TypeScriptVersion.lowest;

for (const directoryVersion of typesVersions) {
if (TypeScriptVersion.compare(directoryVersion, low) < 0) {
continue;
}

const reachesLatest = TypeScriptVersion.compare(directoryVersion, latestTypeScriptVersionToTest) >= 0;
ranges.push({
low,
high: reachesLatest ? latestTypeScriptVersionToTest : (directoryVersion as TypeScriptVersion),
directoryVersion,
});
if (reachesLatest) {
return ranges;
}

const next = TypeScriptVersion.next(directoryVersion as TypeScriptVersion);
assert(next);
low = next;
}

ranges.push({ low, high: latestTypeScriptVersionToTest });
return ranges;
}

async function testTypesVersion(
Expand All @@ -299,7 +337,7 @@ async function testTypesVersion(
}
}

const err = await lint(dirPath, lowVersion, hiVersion, isLatest, expectOnly, tsLocal);
const err = await lint(dirPath, tsconfigs, lowVersion, hiVersion, isLatest, expectOnly, tsLocal);
if (err) {
errors.push(err);
}
Expand Down
65 changes: 48 additions & 17 deletions packages/dtslint/src/lint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@ import { ESLint } from "eslint";
import * as TsType from "typescript";

import { createProgram } from "./createProgram";
import { typeScriptPath } from "./typescript-installer";
import { lintCorsaVersions } from "./lintCorsa";
import { resolveLocalTypeScript, typeScriptPath } from "./typescript-installer";

export async function lint(
dirPath: string,
tsconfigs: readonly string[],
minVersion: TsVersion,
maxVersion: TsVersion,
isLatest: boolean,
Expand All @@ -31,17 +33,38 @@ export async function lint(
return files;
}

const options = getEslintOptions(expectOnly, minVersion, maxVersion, tsLocal);
const eslint = new ESLint(options);
const formatter = await eslint.loadFormatter("stylish");
const results = await eslint.lintFiles(files);
const output = formatter.format(results);
for (const estreePath of estrees) {
if (!estreePath) continue;
const estree = require(estreePath) as typeof import("@typescript-eslint/typescript-estree");
estree.clearCaches();
const versions = range(minVersion, maxVersion);
const legacyVersions: TsVersion[] = [];
const corsaVersions: TsVersion[] = [];
for (const version of versions) {
(usesCorsa(version, tsLocal) ? corsaVersions : legacyVersions).push(version);
}
return output;

const outputs: string[] = [];
if (!expectOnly || legacyVersions.length) {
const options = getEslintOptions(expectOnly, legacyVersions, tsLocal);
const eslint = new ESLint(options);
const formatter = await eslint.loadFormatter("stylish");
const results = await eslint.lintFiles(files);
const output = await formatter.format(results);
if (output) {
outputs.push(output);
}
for (const estreePath of estrees) {
if (!estreePath) continue;
const estree = require(estreePath) as typeof import("@typescript-eslint/typescript-estree");
estree.clearCaches();
}
}

if (corsaVersions.length) {
const output = await lintCorsaVersions(dirPath, tsconfigs, corsaVersions, isLatest, tsLocal, files);
if (output) {
outputs.push(output);
}
}

return outputs.join("\n") || undefined;
}

function getSourceFiles(dirPath: string, isLatest: boolean) {
Expand Down Expand Up @@ -84,11 +107,10 @@ function tryResolve(path: string, options?: { paths?: string[] | undefined }): s

function getEslintOptions(
expectOnly: boolean,
minVersion: TsVersion,
maxVersion: TsVersion,
versions: readonly TsVersion[],
tsLocal: string | undefined,
): ESLint.Options {
const versionsToTest = range(minVersion, maxVersion).map((versionName) => ({
const versionsToTest = versions.map((versionName) => ({
versionName,
path: typeScriptPath(versionName, tsLocal),
}));
Expand All @@ -105,8 +127,8 @@ function getEslintOptions(
{
files: allFiles,
rules: {
// This prevents anyone from disabling this rule.
"@definitelytyped/expect": ["error"],
// This prevents anyone from disabling this rule when it is responsible for ExpectType.
"@definitelytyped/expect": versions.length ? ["error"] : "off",
},
},
],
Expand Down Expand Up @@ -196,11 +218,20 @@ function range(minVersion: TsVersion, maxVersion: TsVersion): readonly TsVersion
const minIdx = TypeScriptVersion.supported.indexOf(minVersion);
assert(minIdx >= 0);
if (maxVersion === TypeScriptVersion.latest) {
return [...TypeScriptVersion.supported.slice(minIdx), TypeScriptVersion.latest];
return TypeScriptVersion.supported.slice(minIdx);
}
const maxIdx = TypeScriptVersion.supported.indexOf(maxVersion as TypeScriptVersion);
assert(maxIdx >= minIdx);
return TypeScriptVersion.supported.slice(minIdx, maxIdx + 1);
}

export type TsVersion = TypeScriptVersion | "local";

function usesCorsa(version: TsVersion, tsLocal: string | undefined): boolean {
if (version !== "local") {
return TypeScriptVersion.compare(version, "7.0") >= 0;
}

assert(tsLocal);
return resolveLocalTypeScript(tsLocal).kind === "corsa";
}
Loading
Loading