| name | typescript-type-safety |
| description | Patterns for avoiding common TypeScript errors, proper type definitions, and early type checking workflows. Use when writing TypeScript code, encountering type errors, or before running tests. Prevents 50-60% of compilation errors and reduces fix cycles from 3-5 to 1-2. |
TypeScript Type Safety
Patterns for avoiding common TypeScript errors, proper type definitions, and early type checking workflows. Prevents 50-60% of compilation errors.
Overview
Problem: TypeScript errors discovered late, requiring 3-5 fix cycles
Solution: Early type checking, proper type definitions, and systematic error prevention
Impact: Reduce fix cycles from 3-5 to 1-2, save 30-60 seconds per task
Early Type Checking Workflow
Immediate Validation
Run type-check immediately after code changes:
npx tsc --noEmit
npm run type-check
Workflow:
- Make code edit
- Run
npx tsc --noEmit immediately
- Fix any errors
- Continue with next edit or testing
Timing:
- After file edits: Run check immediately
- Before browser testing: Run check first
- Before running tests: Run check first
- Before marking complete: Run check to verify
Common Error Patterns
Pattern 1: Export/Import Validation
Problem: Missing exports for imported functions
Solution: Validate exports before imports
import { someFunction } from './utils';
export function someFunction() { }
import { someFunction } from './utils';
Validation pattern:
grep -r "export.*someFunction" src/
Pattern 2: Type Conflicts
Problem: Type conflicts (class vs type names)
Solution: Use distinct names or proper type definitions
class Settings { }
type Settings = { };
class Settings { }
type SettingsData = { };
interface SettingsData { }
Pattern 3: Property Initialization
Problem: Property initialization in constructors
Solution: Initialize in constructor or mark as optional
class GameScene {
private player: Player;
}
class GameScene {
private player: Player;
constructor() {
this.player = new Player();
}
}
class GameScene {
private player?: Player;
}
Pattern 4: Global Type Extensions
Problem: Window extensions not typed
Solution: Declare global type extensions
declare global {
interface Window {
__TEST__?: {
ready: boolean;
sceneKey: string | null;
gameState: () => any;
commands: {
[key: string]: (...args: any[]) => void;
};
};
}
}
Type Definition Patterns
Global Type Extensions
Window interface extensions:
declare global {
interface Window {
__TEST__?: {
ready: boolean;
sceneKey: string | null;
seed: number | null;
gameState: () => GameState;
commands: TestCommands;
};
game?: Phaser.Game;
}
}
Union Types
Flexible object types:
type SpriteOrRectangle = Phaser.GameObjects.Sprite | Phaser.GameObjects.Rectangle;
function handleObject(obj: SpriteOrRectangle) {
if (obj instanceof Phaser.GameObjects.Sprite) {
} else {
}
}
Discriminated Unions
Better type safety with discriminated unions:
type GameEvent =
| { type: 'coin_collected'; value: number }
| { type: 'timer_expired' }
| { type: 'level_complete'; level: number };
function handleEvent(event: GameEvent) {
switch (event.type) {
case 'coin_collected':
break;
case 'timer_expired':
break;
case 'level_complete':
break;
}
}
Property Initialization Patterns
Constructor Initialization
Initialize all properties in constructor:
class GameScene extends Phaser.Scene {
private player: Player;
private score: number;
private timer: number;
constructor() {
super({ key: 'GameScene' });
this.player = new Player();
this.score = 0;
this.timer = 60;
}
}
Optional Properties
Mark properties as optional if not initialized:
class GameScene extends Phaser.Scene {
private player?: Player;
private enemies?: Phaser.Physics.Arcade.Group;
create() {
this.player = new Player();
this.enemies = this.physics.add.group();
}
}
Definite Assignment Assertion
Use ! when property is definitely assigned later:
class GameScene extends Phaser.Scene {
private player!: Player;
create() {
this.player = new Player();
}
}
Export/Import Validation
Check Exports Before Imports
Validate exports exist:
grep -r "export.*functionName" src/
grep -r "^export" src/utils.ts
Consistent Export Patterns
Use consistent export patterns:
export function utilityFunction() { }
export default class MyClass { }
export { function1, function2, class1 };
export function func1() { }
export default function func2() { }
Common Error Fixes
Missing Exports
Error: Module has no exported member 'X'
Fix:
- Check if export exists in source file
- Add export if missing
- Verify export name matches import
export function myFunction() { }
import { myFunction } from './source';
Type Conflicts
Error: Duplicate identifier 'X'
Fix:
- Rename one of the conflicting types
- Use namespace to separate
- Use distinct names
class Settings { }
type SettingsData = { };
Property Initialization
Error: Property 'X' has no initializer
Fix:
- Initialize in constructor
- Mark as optional
- Use definite assignment assertion
constructor() {
this.property = value;
}
private property?: Type;
private property!: Type;
Workflow Integration
Immediate Type Checking
After code changes:
edit_file("src/scenes/GameScene.ts", ...)
npx tsc --noEmit
Before Testing
Always check types before testing:
npx tsc --noEmit && agent-browser open http://localhost:3000
npx tsc --noEmit && npm test
Before Completion
Verify types before marking complete:
npx tsc --noEmit
Best Practices
- Run type-check immediately after code changes
- Fix errors systematically (one type at a time)
- Validate exports before importing
- Use proper type definitions (global extensions, union types)
- Initialize properties in constructor or mark optional
- Use discriminated unions for better type safety
- Check types before testing or marking complete
Integration with Other Skills
- typescript-incremental-check: Uses early type checking workflow
- pre-implementation-check: Validates types before implementation
- task-verification-workflow: Includes type checking in verification
Related Skills
typescript-incremental-check - Fast type checking patterns
pre-implementation-check - Pre-task verification
task-verification-workflow - Task completion verification
Remember
- Check types immediately after code changes
- Fix errors systematically before proceeding
- Validate exports before importing
- Use proper type definitions for global extensions
- Initialize properties correctly
- Prevent 50-60% of compilation errors