TypeScript Type Migrations CLI
This package is a command-line interface (CLI) tool designed to help developers manage migrations of TypeScript type definitions within a project. It leverages the `ts-morph` library to programmatically analyze and modify TypeScript Abstract Syntax Trees (ASTs), enabling structured, versioned changes to existing type declarations across a codebase. Unlike broader migration tools that convert JavaScript to TypeScript, this tool focuses specifically on evolving existing TypeScript types. The current stable version is 1.1.1. The project's development appears to be in maintenance mode, with no significant updates since 2021, suggesting a stable but not actively evolving codebase. Its key differentiator is its focus on managing discrete 'up' and 'down' type migrations.
Common errors
-
Error: Cannot find module 'typescript-migration' or its corresponding type declarations.
cause The package is not installed or the TypeScript configuration does not correctly resolve modules.fixEnsure the package is installed: `npm install typescript-migration` or `yarn add typescript-migration`. For programmatic usage, ensure your `tsconfig.json` has `moduleResolution` set appropriately (e.g., `node`). -
TypeError: project.getSourceFile is not a function (or similar ts-morph error)
cause Incorrect usage of `ts-morph` API within a migration, or `ts-morph` itself might be an incompatible version.fixConsult the `ts-morph` documentation for the correct API usage. Ensure `ts-morph` is installed as a dependency and its version is compatible with `typescript-migration` (though this package is a CLI, your migration files are TypeScript). The `Migration` class provides the `sourceFile` argument directly.
Warnings
- gotcha The project has not seen significant updates since July 2021. While functional for its stated purpose, compatibility with very recent TypeScript versions or new language features may not be guaranteed. Users should test thoroughly when integrating with newer TypeScript compilers.
- gotcha This tool focuses solely on migrating TypeScript *types* via AST manipulation. It is not intended for initial JavaScript-to-TypeScript codebase conversion, for which other tools like Airbnb's `ts-migrate` or TypeStat exist.
- gotcha Migrations can be destructive if not carefully crafted. The `up` and `down` methods should be idempotent and reversible, handling cases where the target types may or may not exist.
Install
-
npm install typescript-migration -
yarn add typescript-migration -
pnpm add typescript-migration
Imports
- Migration
const { Migration } = require('typescript-migration');import { Migration } from 'typescript-migration'; - Migrator
const { Migrator } = require('typescript-migration');import { Migrator } from 'typescript-migration'; - SourceFile
import { SourceFile } from 'ts-morph';
Quickstart
import { Migration } from 'typescript-migration';
import { SourceFile } from 'ts-morph';
import * as path from 'path';
import * as fs from 'fs';
// 1. Define your migration in a file, e.g., 'src/migrations/001-rename-user-interface.ts'
// This migration renames an interface from 'IUser' to 'User'.
class RenameUserInterface extends Migration {
name = 'Rename IUser to User Interface';
async up(sourceFile: SourceFile): Promise<void> {
const oldInterface = sourceFile.getInterface('IUser');
if (oldInterface) {
oldInterface.rename('User');
this.log(`Renamed IUser to User in ${sourceFile.getFilePath()}`);
}
}
async down(sourceFile: SourceFile): Promise<void> {
const newInterface = sourceFile.getInterface('User');
if (newInterface) {
newInterface.rename('IUser');
this.log(`Renamed User back to IUser in ${sourceFile.getFilePath()}`);
}
}
}
// For demonstration, create a dummy TypeScript file to migrate.
const dummyFilePath = path.join(process.cwd(), 'temp-source.ts');
const dummyContent = `interface IUser { id: string; name: string; }\nconst user: IUser = { id: '1', name: 'Alice' };`;
// For CLI usage, you would place this migration file in a designated migrations directory.
// For programmatic usage (shown here for simplicity):
async function runMigrationProgrammatically() {
// Ensure temp-source.ts exists for the demo
fs.writeFileSync(dummyFilePath, dummyContent);
console.log('Created temp-source.ts');
// To run this via the CLI, you would save RenameUserInterface to a file
// and execute: npx typescript-migration run --up path/to/migrations_folder
// Programmatic execution example:
const { Migrator } = await import('typescript-migration');
const migrator = new Migrator();
// Instantiate your migration
const migrationInstance = new RenameUserInterface();
// Apply the 'up' migration to the dummy file
console.log('\n--- Running UP migration ---');
await migrator.run([migrationInstance], [dummyFilePath], 'up');
console.log('Migration UP finished.');
// Verify changes (read the file content after migration)
const updatedContent = fs.readFileSync(dummyFilePath, 'utf8');
console.log('\nUpdated temp-source.ts content:\n', updatedContent);
// Revert the 'down' migration
console.log('\n--- Running DOWN migration ---');
await migrator.run([migrationInstance], [dummyFilePath], 'down');
console.log('Migration DOWN finished.');
const revertedContent = fs.readFileSync(dummyFilePath, 'utf8');
console.log('\nReverted temp-source.ts content:\n', revertedContent);
// Clean up
fs.unlinkSync(dummyFilePath);
console.log('\nCleaned up temp-source.ts');
}
runMigrationProgrammatically().catch(console.error);