home

About

exists because any is the one TypeScript type that switches the type checker off. Every as any is a place where a refactor can break production without a single red squiggle. The name is the joke; the tool is serious.

Why any matters

any is contagious. A value typed any keeps that type through property access, calls and assignments, so one cast at an API boundary silently removes checks from everything downstream. Errors that TypeScript would have caught at compile time turn into undefined is not a function at runtime.

The fix is nearly always cheap: unknown where the shape is genuinely unknown (it forces a check before use), an interface where the shape is known, and a type guard or schema validator at the boundary where data comes in.

What counts

The scanner parses every .ts, .tsx, .mts and .cts file with the TypeScript compiler API and walks the syntax tree. Only an any type node counts: the word in a comment, a string or a variable called any does not. Each finding is classified by where it sits in the tree:

Limits of the method

Automatic scanning

Besides the scans visitors start, a small crawler discovers popular public TypeScript repositories through GitHub's search API (recently pushed popular repositories, new repositories gaining stars, and a rotating set of topics such as nextjs, react and nodejs) and scans a handful of them every twenty minutes. A repository is only scanned again when its default branch has moved since the last scan, so the traffic stays small: a few GitHub API requests per run, well within the limits GitHub publishes. Archived repositories, forks, templates and empty repositories are skipped. The results feed the trending page and each repository's history page.

Only repository metadata (name, stars, default branch, push date) and the code snippets around each finding are stored. No commit authors, contributor names or e-mail addresses are fetched or shown.

Opting out

Maintainers who would rather not see their repository here can opt out in either of two ways:

  • add an empty .fasanyignore file to the repository root, or
  • add "fasany": { "optOut": true } to the root package.json.

The next time the repository is scanned, by the crawler or by a visitor, the opt-out is noticed, every stored scan and finding for it is deleted, and it is not scanned again. For an immediate removal, or if you want a repository excluded without changing it, write to hbouma01@gmail.com.

Badges, resolving and rate limits

/badge/owner/repo.svg shows the count from the latest finished scan of that repository and is cached for an hour. Scan again after fixing to update it.

Signed-in users can mark a finding resolved, optionally with the pull request link. That only records progress on this site; it does not change the repository. The leaderboard counts resolved findings per person, by display name.

Scans use GitHub's API, which allows a limited number of requests per hour, and each visitor can start a handful of scans per quarter hour. A scan of the same repository and ref within ten minutes returns the existing result. Everything is deleted after 30 days.