Porting JS to TypeScript with Claude Code

By default Claude Code struggles to port JavaScript to TypeScript. Often the types it generates are filled with usages of any or inline cast like x as unknown as { bleh(): void }. In the worst cases it abandons entire files and inserts @ts-nocheck disabling typechecking for those files altogether.

The problem is Claude Code prioritizes a passing typecheck after every single edit. It treats a successful tsc run as a strict requirement; if a cast is the quickest way to resolve an immediate error, it will use one. Each edit is locally successful but the overall result is poor. This leads to a codebase cluttered with any and as unknown as.

This is the wrong approach. Effective typing requires knowledge about the shared architecture of a program not just reacting to typecheck errors from tsc.

Two Pass Workflow

The solution is straightforward: port the codebase in two passes and prevent Claude from running tsc during the first pass. By removing the immediate requirement for a successful typecheck we force Claude Code to focus on designing types from its own reasoning rather then simply silencing errors.

  • Pass 1: Add types: Claude is forced to add type annotations without invoking tsc, forcing it to build the types entirely from its own reasoning and the context window it creates by scanning the codebase.
  • Pass 1.5: Coherence Review: Claude reviews the ported files for global type coherency. Typechecking is still disabling.
  • Pass 2: Resolving Errors (Typechecker Enabled). Only now does Claude run tsc and resolve (any remaining) type errors.

Hard Limits

It’s also useful to set a few hard limits for claude code:

  • No use of unknown or any during phase 1 and 1.5 at all.
  • any limited to X usages across the entire codebase for pass 2.
  • Enable strictNullChecks from the beginning.

Establish a Testing Baseline

It’s important to make sure the old JS codebase has adequate unit tests. You can have Claude Code generate these for you, e.g.: First, review the core logic in [target file/directory] and generate a comprehensive suite of unit tests for the existing JavaScript. Ensure the tests pass. Once established, use the js-to-ts-port skill to port the code to TypeScript, using the test suite to verify the logic remains intact.


I have packaged this methodology as a Claude Code skill: js-to-ts-port.

Leave a comment