Labels
BugA bug in TypeScriptA bug in TypeScript
Milestone
Description
🔎 Search Terms
singleThreaded, --checkers, checker pool, checkers declaration any, nondeterministic declaration, circularly references itself keyof, TS2456
🕗 Version & Regression Information
- This is the behavior in every version multi-threaded I tried, back to 7.0
⏯ Playground Link
💻 Code
status.ts
import type { Key } from "./types";
export class StatusClass {
RUNNING: Status = "RUNNING";
[key: string]: Status;
}
export type Status = keyof StatusClass | "";
export const statusFromAPI: { [key: Key]: Status } = {};consumer.ts
import { statusFromAPI } from "./status";
export const current = statusFromAPI["RUNNING"];types.ts:
export type Key = string;🙁 Actual behavior
The consumer.d.ts output gets incorrectly inferred as any:
export declare const current: any;
🙂 Expected behavior
Both TS6 and --singleThreaded emit the correct type:
export declare const current: import("./status").Status;
Additional information about the issue
The emitted type depends on how many checkers there are, which really means how the files are split across them. Status below means import("./status").Status. Every run exits 0 with no diagnostics:
| Version | --singleThreaded / --checkers 1 |
--checkers 2 |
--checkers 3 |
default (4) | --checkers 8 |
|---|---|---|---|---|---|
| 6.0.3 (one checker) | Status |
n/a | n/a | n/a | n/a |
| 7.0.2 | Status |
any |
any |
any |
any |
| 7.1.0-beta | Status |
Status |
any |
any |
any |
| 7.1.0-dev.20261028 | Status |
Status |
any |
any |
any |
Each configuration gives the same result on every run (10 of 10 runs of the 7.1.0-beta default were identical), so this comes from how files are partitioned, not from a race. The .d.ts silently loses the type, and the build gives no sign that anything went wrong.
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScript
Activity
blickly commentedon Nov 7, 2026
Even though it's not what I saw in "the wild" for this bug, the same issue can be extended pretty easily to a case where running with a single checker correctly catches a type error, and running with 3 or more checkers fails to find the error.
e.g.
gives a:
diagnostic in TS6 / tsgo
--singleThreaded/ etc., but fails to find the error when checking with 3 or more checkers.RyanCavanaugh commentedon Nov 10, 2026
Should be fixed by #65293
jakebailey commentedon Nov 10, 2026
Sadly Ben Lickly (@blickly) already confirmed it does not, which is scary