typescript-refactorer
TypeScript Refactorer
Before generating any output, read config/defaults.md and adapt all patterns, imports, and code examples to the user's configured stack.
Analysis Process
- Scan the specified files for type-related code smells
- Categorize issues by severity
- Provide corrected code for each issue
Code Smells to Detect
Explicit any Usage
// BAD
function process(data: any) {
return data.value;
}
// GOOD: Use specific type or generic
function process<T extends { value: unknown }>(data: T) {
return data.value;
}
// GOOD: Use unknown with type guard
function process(data: unknown) {
if (isValidData(data)) {
return data.value;
}
throw new Error('Invalid data');
}
Implicit any from Missing Types
// BAD: Parameter implicitly has 'any' type
function calculate(x, y) {
return x + y;
}
// GOOD
function calculate(x: number, y: number): number {
return x + y;
}
Unnecessary Type Assertions
// BAD: Assertion when type is already known
const value = getValue() as string; // getValue already returns string
// BAD: Double assertion (type laundering)
const data = response as unknown as User;
// GOOD: Fix the source type or use type guard
const data = isUser(response) ? response : null;
Overly Broad Union Types
// BAD
type Status = string;
// GOOD: Use literal union
type Status = 'pending' | 'active' | 'completed' | 'failed';
// BAD
type Result = { success: boolean; data?: any; error?: string };
// GOOD: Discriminated union
type Result =
| { success: true; data: User }
| { success: false; error: string };
Missing Discriminated Unions
// BAD: Ambiguous state
interface State {
loading: boolean;
data: User | null;
error: Error | null;
}
// GOOD: Discriminated union makes invalid states unrepresentable
type State =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'success'; data: User }
| { status: 'error'; error: Error };
Implicit Return Types
// BAD: Return type inferred as complex union
function getUser(id: string) {
if (!id) return null;
return fetchUser(id); // Returns Promise<User>
}
// Inferred: (id: string) => null | Promise<User>
// GOOD: Explicit return type catches errors
function getUser(id: string): Promise<User | null> {
if (!id) return Promise.resolve(null);
return fetchUser(id);
}
Non-null Assertions (!)
// BAD: Hiding potential null issues
const name = user!.name;
// GOOD: Explicit null check
const name = user?.name ?? 'Anonymous';
// GOOD: Early return / throw
if (!user) throw new Error('User required');
const name = user.name;
Type-unsafe Object Access
// BAD
const value = obj['dynamicKey'];
// GOOD: Use Record type
const obj: Record<string, number> = {};
const value = obj['dynamicKey']; // value: number | undefined
// BETTER: Use Map for dynamic keys
const map = new Map<string, number>();
const value = map.get('dynamicKey');
Missing readonly
// BAD: Mutable when shouldn't be
interface Config {
apiUrl: string;
timeout: number;
}
// GOOD: Immutable config
interface Config {
readonly apiUrl: string;
readonly timeout: number;
}
// Or use Readonly utility
type Config = Readonly<{
apiUrl: string;
timeout: number;
}>;
Function Overloads Instead of Unions
// BAD: Unclear relationship between input and output
function parse(input: string | Buffer): string | Uint8Array;
// GOOD: Overloads make it explicit
function parse(input: string): string;
function parse(input: Buffer): Uint8Array;
function parse(input: string | Buffer): string | Uint8Array {
// Implementation
}
Output Format
## TypeScript Analysis
### Critical (type safety compromised)
- **Explicit any** in `src/utils/api.ts:23`
- Issue: `data: any` parameter loses all type information
- Fix: [code block with typed version]
### Warnings (potential issues)
- **Missing discriminated union** in `src/types/state.ts:5`
- Issue: State type allows invalid combinations
- Fix: [code block with discriminated union]
### Suggestions (improvements)
- **Implicit return type** in `src/services/user.ts:45`
- Issue: Complex inferred return type
- Fix: [code block with explicit return type]
### Summary
- Critical: X issues
- Warnings: X issues
- Suggestions: X issues
Before/After Verification
After suggesting refactoring changes, verify that the refactored code is type-correct by checking for: consistent type usage across the changed files, no introduced type errors in function signatures, all imports still valid. If a suggested refactoring would break a downstream consumer, flag it: BREAKING: this change affects [file/function] — update those references too.
Reference
See references/code-smells.md for a complete catalog of TypeScript anti-patterns.
More from nembie/claude-code-skills
code-reviewer
Automated code review for security, performance, and maintainability. Use when asked for code review, security audit, quality check, PR review, or to find issues in code.
22auth-scaffold
Scaffold authentication with Auth.js (NextAuth v5), including providers, session handling, middleware protection, and role-based access. Use when asked to set up auth, add login, protect routes, or implement authentication.
3test-generator
Generate unit and integration tests for API routes, utilities, React components, and hooks. Use when asked to generate tests, write unit tests, create integration tests, add test coverage, or test a component/route/function.
3nextjs-route-generator
Scaffold Next.js App Router API routes with Zod validation, error handling, and TypeScript types. Use when asked to create API routes, REST endpoints, CRUD operations, or scaffold a Next.js backend.
3prisma-query-optimizer
Analyze Prisma queries for performance issues and suggest optimizations. Use when asked to optimize, analyze, audit, or review Prisma queries, or when investigating slow database operations in a Prisma-based project.
3git-commit-composer
Generate conventional commit messages from staged git changes. Use when asked to compose a commit message, write a commit, generate conventional commits, or describe staged changes.
3