cd /news/developer-tools/one-rule-found-a-bug-that-typescript… · home › topics › developer-tools › article
[ARTICLE · art-153244] src=breakspec.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

One rule found a bug that TypeScript’s test suite missed.

Breakspec, a tool that checks code against invariant rules, found a bug in Microsoft's TypeScript compiler after 19 inputs: declaration files the compiler emits for constants that overflow to Infinity, such as `export default 1.7976931348623159e308;`, contain initializers like `declare const _default = Infinity;` that the same compiler then rejects with error TS1254. The bug, filed publicly as microsoft/TypeScript#64760, also affects TypeScript 6.0.3 and predates the Go rewrite, and no existing TypeScript test covered it. A fix written with Claude Code, which gives such constants the type `number` instead of an initializer, passed 300 fresh inputs and TypeScript's Go test suite of 64 packages plus a new compiler test, and is under review.

read4 min views6 publishedOct 19, 2026
One rule found a bug that TypeScript’s test suite missed.
Image: source

We pointed Breakspec at the TypeScript repository with one rule: the declaration files the compiler writes must be valid TypeScript. It broke that rule after 19 inputs. The bug is public as microsoft/TypeScript#64760, and a fix is under review.

  • Rule
  • Declaration files the compiler writes must be valid TypeScript.
  • Smallest input
  • export default 1.7976931348623159e308;
  • Compiler output
  • declare const _default = Infinity;
  • Result
  • The same compiler rejects that file with error TS1254.
  • Also affects
  • TypeScript 6.0.3
  • Fix
  • Written with Claude Code from Breakspec’s fix request, verified by Breakspec, under review.

The bug #

A number too large for a double, like 1e400, evaluates to Infinity. When the compiler writes a declaration file for a constant with that value, it writes Infinity as the initializer:

// m.ts
export const a = 1e400;
export const b = -1e400;
export class C {
    static readonly e = 1e400;
}
export default 1.7976931348623159e308;
js
// m.d.ts, as the compiler wrote it
export declare const a = Infinity;
export declare const b = -Infinity;
export declare class C {
    static readonly e = Infinity;
}
declare const _default = Infinity;
export default _default;

The compiler then rejects its own output. Each of those initializers is error TS1254: an ambient constant must be initialized with a string or numeric literal, and Infinity is a name, not a literal. A library that exports a constant like this ships declaration files that fail type-checking for its users, unless they skip checking library types.

It isn’t new #

TypeScript 6.0.3 writes the same initializers. We checked in the TypeScript Playground. The bug predates the move to the new compiler written in Go, and no existing TypeScript test covered it.

How Breakspec found it #

  • We used the repository as it was on its main branch, unchanged.
  • We gave it one rule, on CommandLine , the compiler’s entry point: declaration files the compiler writes are valid TypeScript. The check compiles a program with declarations on, then compiles those declarations with the same compiler.
  • Breakspec ran the compiler in an isolated sandbox and broke the rule after 19 inputs. The smallest is one line, export default 1.7976931348623159e308; , just past the largest number a double can hold.

The fix, and how it was checked #

Breakspec turned the failure into a fix request, and Claude Code wrote the fix from it: a constant whose value is Infinity or NaN gets the type number instead of an initializer.

// m.d.ts, with the fix
export declare const a: number;
export declare const b: number;
export declare class C {
    static readonly e: number;
}
declare const _default: number;
export default _default;
  • Breakspec replayed the failing input against the fix, then tried 300 fresh inputs. None failed.
  • TypeScript’s own Go test suite passes: 64 packages, plus a new compiler test. Without the fix, that test records 6 TS1254 errors.
  • References to enum members with these values, like E.A , were already valid and are left alone.
  • The pull request says the fix was written with AI assistance, as TypeScript’s contribution guidelines ask, and a person is responsible for it in review.

The recording #

The recording mixes live dashboard footage with explanation slides. The dashboard parts were recorded live on the real repository: approving the rules, the run that finds the bug, and the check of the fix. The slides show the fix itself, TypeScript’s test results and the commit. The two long waits are sped up, with an on-screen clock showing the real time.

What this shows #

The TypeScript compiler has a large test suite, and it passed. The bug sat where no example test looked, and one rule about what must always be true found it. Breakspec does the same for the code your agents write: it works out what must hold, proves each failure, has your agent fix it and checks the fix.

Join the waitlist

TypeScript is a trademark of Microsoft Corporation. Breakspec isn’t affiliated with or endorsed by Microsoft. The issue and pull request are public on GitHub; their status may have changed since this page was written.

── more in #developer-tools 4 stories · sorted by recency
── more on @breakspec 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/one-rule-found-a-bug…] indexed:0 read:4min 2026-10-19 · —