Skip to content

Conversation

@DanielRosenwasser
Copy link
Member

@DanielRosenwasser DanielRosenwasser commented Jan 15, 2026

As preparation for #62333, I looked at all tests that had a difference in errors when --noImplicitAny defaulted to true. I basically figured that anything that fails at --noImplicitAny would fail on --strict as a whole.

There's a lot that changed, so I wrote a script that prepended // @strict: false to the majority of the tests that had affected output (see below). This was only possible after merging #62987. The script bailed out only if:

  • the test was UTF-16 (I was too lazy to maintain the encoding and I wanted to be carefuly)
  • the test contained a UTF-8 BOM (I wanted to more-carefully investigate these or leave as-is, similar too the above)
  • the test already contained @strict or @noImplicitAny somewhere (makes the script re-runnable)
  • the test contained any non-ASCII characters (again, why take a risk?)
  • lone carriage return newlines (none in affected tests thankfully)

One thing you might note about the script is that it operates over globs. I got the globs in a somewhat hacky way - basically, I ran git status after accepting baselines, and replaced

  • tests/baselines/reference/ with tests/**/
  • .errors.txt with *.ts, and
  • /\(.+\)/ with nothing.

So this won't be all the tests, and technically I might have slapped // @strict: false on a few tests that didn't need it. But that is fine since they were already running with strict off, and we're just trying to clear noise from error baselines (both for maintenance and for the eventual PR).

Prepending script
import { readFile, writeFile, glob } from "fs/promises";
import { join } from "path";

const inputFile = process.argv[2];

if (!inputFile) {
    console.error("Usage: node prepend-strict-false.mjs <file-with-globs>");
    process.exit(1);
}

const content = await readFile(inputFile, "utf-8");
const lines = content.split(/\r?\n/).filter(line => line.trim() !== "");

for (const pattern of lines) {
    const files = glob(pattern, { withFileTypes: true });
    
    for await (const file of files) {
        if (!file.isFile()) {
            continue;
        }
        const filePath = join(file.parentPath, file.name);
        try {
            const buffer = await readFile(filePath);
            const len = buffer.length;

            if (len >= 2 && buffer[0] === 0xFE && buffer[1] === 0xFF) {
                // Big endian UTF-16 byte order mark detected. Since big endian is not supported by node.js,
                // flip all byte pairs and treat as little endian.
                console.log(`Skipping ${filePath}: contains big-endian UTF-16 BOM`);
                continue;
            }
            if (len >= 2 && buffer[0] === 0xFF && buffer[1] === 0xFE) {
                // Little endian UTF-16 byte order mark detected
                console.log(`Skipping ${filePath}: contains little-endian UTF-16 BOM`);
                continue;
            }
            if (len >= 3 && buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
                // UTF-8 byte order mark detected
                console.log(`Skipping ${filePath}: contains UTF-8 BOM`);
                continue;
            }

            const fileContent = buffer.toString("utf-8");
            
            // Check for @noImplicitAny or @strict
            if (fileContent.includes("@noImplicitAny")) {
                console.log(`Skipping ${filePath}: contains @noImplicitAny`);
                continue;
            }
            if (fileContent.includes("@strict")) {
                console.log(`Skipping ${filePath}: contains @strict`);
                continue;
            }
            
            // Check for non-ASCII characters
            if (/[^\x00-\x7F]/.test(fileContent)) {
                console.log(`Skipping ${filePath}: contains non-ASCII characters`);
                continue;
            }

            // Check for an abnormal newline
            const hasLoneCR = /\r(?!\n)/.test(fileContent);
            if (hasLoneCR) {
                console.log(`Skipping ${filePath}: contains lone carriage return characters`);
                continue;
            }

            const firstNewline = fileContent.match(/\r?\n/);
            if (!firstNewline) {
                console.log(`Skipping ${filePath}: single line file with ambiguous newline strategy`);
                continue;
            }

            // Prepend // @strict: false
            const newContent = "// @strict: false" + firstNewline + fileContent;
            await writeFile(filePath, newContent, "utf-8");
            console.log(`Updated ${filePath}`);
        } catch (err) {
            console.error(`Error processing ${filePath}: ${err}`);
        }
    }
}

console.log("Done!");

Copilot AI review requested due to automatic review settings January 15, 2026 06:46
@github-project-automation github-project-automation bot moved this to Not started in PR Backlog Jan 15, 2026
@typescript-bot typescript-bot added Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Jan 15, 2026
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR prepares TypeScript's test suite for enabling --noImplicitAny by default (as part of #62333). The change involved analyzing all tests that would have different error output when --noImplicitAny defaults to true, and prepending // @strict: false to tests that should continue to allow implicit any types.

Changes:

  • Added // @strict: false compiler directive to test files that rely on implicit any behavior
  • Used an automated script to prepend the directive while safely handling UTF-16, UTF-8 BOM, non-ASCII characters, and files that already had @strict or @noImplicitAny directives

Reviewed changes

Copilot reviewed 300 out of 2034 changed files in this pull request and generated no comments.

File Description
tests/cases/compiler/*.ts (200+ files) Added // @strict: false directive to compiler test cases that need to preserve implicit any behavior
tests/baselines/reference/tsserver/fourslashServer/*.js (5 files) Updated baseline files to reflect the addition of "strict": false in tsconfig.json compiler options and adjusted line numbers in diagnostic messages

@DanielRosenwasser
Copy link
Member Author

This history is already a nightmare...

@jakebailey
Copy link
Member

On one hand, I feel bad locking so many tests into a mode we basically don't want anyone using, but on the other, that is what they were testing before, so, there's not much difference....

@github-project-automation github-project-automation bot moved this from Not started to Needs merge in PR Backlog Jan 15, 2026
@DanielRosenwasser
Copy link
Member Author

DanielRosenwasser commented Jan 15, 2026

The problem I'm trying to solve is that I don't want people opening the error baselines of a test to have to deal with dozens of irrelevant errors.

Maybe we could add some sort of comment to explain the reason they're off? Then in the future someone could forward-migrate the tests. But maybe just having this PR is enough, and I don't realistically think anyone is going to do that work anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

Status: Needs merge

Development

Successfully merging this pull request may close these issues.

5 participants