Loading...
Automatically runs TypeScript compiler checks after editing .ts or .tsx files to catch type errors early
{
"hookConfig": {
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/typescript-compilation-checker.sh",
"matchers": [
"write",
"edit"
]
}
}
},
"scriptContent": "#!/bin/bash\n\n# Read the tool input from stdin\nINPUT=$(cat)\nTOOL_NAME=$(echo \"$INPUT\" | jq -r '.tool_name')\nFILE_PATH=$(echo \"$INPUT\" | jq -r '.tool_input.file_path // .tool_input.path // \"\"')\n\nif [ -z \"$FILE_PATH\" ]; then\n exit 0\nfi\n\n# Check if this is a TypeScript file\nif [[ \"$FILE_PATH\" == *.ts ]] || [[ \"$FILE_PATH\" == *.tsx ]]; then\n echo \"🔍 TypeScript Compilation Checker - Validating TypeScript code...\"\n echo \"📄 File: $FILE_PATH\"\n \n # Check if file exists\n if [ ! -f \"$FILE_PATH\" ]; then\n echo \"⚠️ File not found: $FILE_PATH\"\n exit 1\n fi\n \n # Check if TypeScript is available\n if ! command -v npx >/dev/null 2>&1; then\n echo \"⚠️ npx not found - please install Node.js\"\n exit 1\n fi\n \n if ! npx tsc --version >/dev/null 2>&1; then\n echo \"⚠️ TypeScript not found - install with: npm install -g typescript\"\n exit 1\n fi\n \n # Get TypeScript version\n TS_VERSION=$(npx tsc --version 2>/dev/null | grep -o '[0-9]\\+\\.[0-9]\\+\\.[0-9]\\+')\n echo \"📦 TypeScript version: $TS_VERSION\"\n \n # Check for tsconfig.json\n if [ -f \"tsconfig.json\" ]; then\n echo \"⚙️ Using project tsconfig.json\"\n CONFIG_FLAG=\"\"\n else\n echo \"⚠️ No tsconfig.json found - using default configuration\"\n CONFIG_FLAG=\"--strict --target es2020 --module esnext --moduleResolution node\"\n fi\n \n echo \"🔍 Running TypeScript compilation check...\"\n \n # Run TypeScript compiler in no-emit mode\n if npx tsc --noEmit $CONFIG_FLAG \"$FILE_PATH\" 2>&1; then\n echo \"✅ TypeScript compilation successful - no type errors found\"\n \n # Additional file analysis\n echo \"\"\n echo \"📊 File Analysis:\"\n \n # Count interfaces, types, classes\n INTERFACES=$(grep -c '^interface\\\\|^export interface' \"$FILE_PATH\" 2>/dev/null || echo 0)\n TYPES=$(grep -c '^type\\\\|^export type' \"$FILE_PATH\" 2>/dev/null || echo 0)\n CLASSES=$(grep -c '^class\\\\|^export class' \"$FILE_PATH\" 2>/dev/null || echo 0)\n FUNCTIONS=$(grep -c '^function\\\\|^export function' \"$FILE_PATH\" 2>/dev/null || echo 0)\n \n echo \" • Interfaces: $INTERFACES\"\n echo \" • Type aliases: $TYPES\"\n echo \" • Classes: $CLASSES\"\n echo \" • Functions: $FUNCTIONS\"\n \n # Check for any usage\n if grep -q ': any' \"$FILE_PATH\" 2>/dev/null; then\n ANY_COUNT=$(grep -c ': any' \"$FILE_PATH\" 2>/dev/null || echo 0)\n echo \" • ⚠️ 'any' types found: $ANY_COUNT (consider more specific types)\"\n fi\n \n # Check for strict mode compliance\n if grep -q '\"use strict\"' \"$FILE_PATH\" 2>/dev/null; then\n echo \" • ✅ Strict mode enabled\"\n fi\n \n else\n echo \"❌ TypeScript compilation failed - type errors detected\"\n echo \"\"\n echo \"💡 Common fixes:\"\n echo \" • Check for missing type annotations\"\n echo \" • Verify import statements are correct\"\n echo \" • Ensure all variables are properly typed\"\n echo \" • Check for undefined/null value handling\"\n echo \" • Verify function return types match implementation\"\n exit 1\n fi\n \n # Project-wide TypeScript health check\n echo \"\"\n echo \"🏗️ Project TypeScript Health:\"\n \n # Count total TypeScript files\n TS_FILES=$(find . -name \"*.ts\" -o -name \"*.tsx\" | grep -v node_modules | wc -l)\n echo \" • Total TS/TSX files: $TS_FILES\"\n \n # Check if project compiles\n if [ -f \"tsconfig.json\" ]; then\n echo \" • 🔍 Checking project compilation...\"\n if npx tsc --noEmit >/dev/null 2>&1; then\n echo \" • ✅ Project compiles successfully\"\n else\n echo \" • ⚠️ Project has compilation errors - run 'npx tsc --noEmit' for details\"\n fi\n fi\n \n echo \"\"\n echo \"💡 TypeScript Best Practices:\"\n echo \" • Use strict TypeScript configuration\"\n echo \" • Avoid 'any' types when possible\"\n echo \" • Use union types for multiple possibilities\"\n echo \" • Implement proper error handling with typed exceptions\"\n echo \" • Use interface segregation principle\"\n \n echo \"\"\n echo \"🎯 TypeScript validation complete!\"\n \nelse\n echo \"ℹ️ File is not a TypeScript file: $FILE_PATH\"\nfi\n\nexit 0"
}.claude/hooks/~/.claude/hooks/{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/typescript-compilation-checker.sh",
"matchers": [
"write",
"edit"
]
}
}
}#!/bin/bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a TypeScript file
if [[ "$FILE_PATH" == *.ts ]] || [[ "$FILE_PATH" == *.tsx ]]; then
echo "🔍 TypeScript Compilation Checker - Validating TypeScript code..."
echo "📄 File: $FILE_PATH"
# Check if file exists
if [ ! -f "$FILE_PATH" ]; then
echo "⚠️ File not found: $FILE_PATH"
exit 1
fi
# Check if TypeScript is available
if ! command -v npx >/dev/null 2>&1; then
echo "⚠️ npx not found - please install Node.js"
exit 1
fi
if ! npx tsc --version >/dev/null 2>&1; then
echo "⚠️ TypeScript not found - install with: npm install -g typescript"
exit 1
fi
# Get TypeScript version
TS_VERSION=$(npx tsc --version 2>/dev/null | grep -o '[0-9]\+\.[0-9]\+\.[0-9]\+')
echo "📦 TypeScript version: $TS_VERSION"
# Check for tsconfig.json
if [ -f "tsconfig.json" ]; then
echo "⚙️ Using project tsconfig.json"
CONFIG_FLAG=""
else
echo "⚠️ No tsconfig.json found - using default configuration"
CONFIG_FLAG="--strict --target es2020 --module esnext --moduleResolution node"
fi
echo "🔍 Running TypeScript compilation check..."
# Run TypeScript compiler in no-emit mode
if npx tsc --noEmit $CONFIG_FLAG "$FILE_PATH" 2>&1; then
echo "✅ TypeScript compilation successful - no type errors found"
# Additional file analysis
echo ""
echo "📊 File Analysis:"
# Count interfaces, types, classes
INTERFACES=$(grep -c '^interface\\|^export interface' "$FILE_PATH" 2>/dev/null || echo 0)
TYPES=$(grep -c '^type\\|^export type' "$FILE_PATH" 2>/dev/null || echo 0)
CLASSES=$(grep -c '^class\\|^export class' "$FILE_PATH" 2>/dev/null || echo 0)
FUNCTIONS=$(grep -c '^function\\|^export function' "$FILE_PATH" 2>/dev/null || echo 0)
echo " • Interfaces: $INTERFACES"
echo " • Type aliases: $TYPES"
echo " • Classes: $CLASSES"
echo " • Functions: $FUNCTIONS"
# Check for any usage
if grep -q ': any' "$FILE_PATH" 2>/dev/null; then
ANY_COUNT=$(grep -c ': any' "$FILE_PATH" 2>/dev/null || echo 0)
echo " • ⚠️ 'any' types found: $ANY_COUNT (consider more specific types)"
fi
# Check for strict mode compliance
if grep -q '"use strict"' "$FILE_PATH" 2>/dev/null; then
echo " • ✅ Strict mode enabled"
fi
else
echo "❌ TypeScript compilation failed - type errors detected"
echo ""
echo "💡 Common fixes:"
echo " • Check for missing type annotations"
echo " • Verify import statements are correct"
echo " • Ensure all variables are properly typed"
echo " • Check for undefined/null value handling"
echo " • Verify function return types match implementation"
exit 1
fi
# Project-wide TypeScript health check
echo ""
echo "🏗️ Project TypeScript Health:"
# Count total TypeScript files
TS_FILES=$(find . -name "*.ts" -o -name "*.tsx" | grep -v node_modules | wc -l)
echo " • Total TS/TSX files: $TS_FILES"
# Check if project compiles
if [ -f "tsconfig.json" ]; then
echo " • 🔍 Checking project compilation..."
if npx tsc --noEmit >/dev/null 2>&1; then
echo " • ✅ Project compiles successfully"
else
echo " • ⚠️ Project has compilation errors - run 'npx tsc --noEmit' for details"
fi
fi
echo ""
echo "💡 TypeScript Best Practices:"
echo " • Use strict TypeScript configuration"
echo " • Avoid 'any' types when possible"
echo " • Use union types for multiple possibilities"
echo " • Implement proper error handling with typed exceptions"
echo " • Use interface segregation principle"
echo ""
echo "🎯 TypeScript validation complete!"
else
echo "ℹ️ File is not a TypeScript file: $FILE_PATH"
fi
exit 0tsc --noEmit checks entire project instead of single file
TypeScript follows imports checking dependencies. Add --skipLibCheck: 'tsc --noEmit --skipLibCheck "$FILE_PATH"' or use --isolatedModules for single-file validation without imports.
Compilation fails with module resolution errors for node_modules
Missing @types packages or wrong moduleResolution. Install types: 'npm install --save-dev @types/node @types/react'. Set tsconfig: '"moduleResolution": "node"' or "bundler".
Hook shows success but VSCode still displays type errors
Different TS versions between CLI and editor. Check: 'npx tsc --version' vs VSCode version. Sync: install workspace TS: 'npm install --save-dev typescript@latest'. Restart VSCode.
'any' type detection misses implicit any from missing type annotations
grep pattern only finds explicit ': any'. Enable noImplicitAny in tsconfig.json. Or check tsc output: parse 'implicitly has an any type' from compilation errors for complete detection.
Project-wide health check freezes on large monorepos
Full tsc scans thousands of files. Skip or timeout: 'timeout 10 npx tsc --noEmit >/dev/null 2>&1' with exit code check. Or remove: comment out project compilation section.
Loading reviews...
Join our community of Claude power users. No spam, unsubscribe anytime.
Automated accessibility testing and compliance checking for web applications following WCAG guidelines
Automatically generates or updates API documentation when endpoint files are modified
Automatically formats code files after Claude writes or edits them using Prettier, Black, or other formatters