Back to catalogue
ValidationPostToolBatch
Typecheck after parallel file edits
One tsc pass after a batch, not one per file
Runs tsc --noEmit once after a full batch of parallel tool calls that include TypeScript file edits. Avoids redundant per-file tsc invocations and reports type errors back to Claude as context for the next turn.
What does the Typecheck after parallel file edits hook do?
Typecheck after parallel file edits is a Claude Code PostToolBatch hook. It fires automatically at that lifecycle event — outside the model, so it can't be skipped or forgotten. One tsc pass after a batch, not one per file.
Use cases
- Run a single TypeScript check after Claude edits multiple .ts/.tsx files in parallel
- Surface type errors immediately after batch refactors or code generation
- Reduce tsc invocation overhead versus per-file PostToolUse hooks
Tags
#typescript#typecheck#batch#validation
settings.json fragment
{
"hooks": {
"PostToolBatch": [
{
"hooks": [
{
"command": "node $CLAUDE_PROJECT_DIR/.claude/hooks/post-tool-batch-typecheck.mjs",
"type": "command"
}
]
}
]
}
}Script · .claude/hooks/post-tool-batch-typecheck.mjs
#!/usr/bin/env node
// Vérifie les types TypeScript après un lot d'écritures (PostToolBatch)
import { readFileSync } from 'fs';
import { execSync } from 'child_process';
import { fileURLToPath } from 'url';
function defaultExec(cmd) {
return execSync(cmd, { stdio: 'pipe', timeout: 30_000 });
}
export function run(input, { exec = defaultExec } = {}) {
const calls = input.tool_calls ?? [];
const hasTs = calls.some(
(c) => ['Write', 'Edit'].includes(c.tool_name) && /\.tsx?$/.test(c.tool_input?.file_path ?? ''),
);
if (!hasTs) return null;
try {
exec('npx --no-install tsc --noEmit --pretty false 2>&1');
return null;
} catch (e) {
const out = (e.stdout ?? e.stderr ?? '').toString().slice(0, 2000);
return {
hookSpecificOutput: {
hookEventName: 'PostToolBatch',
additionalContext: `TypeScript errors after batch edit:\n${out}`,
},
};
}
}
/* v8 ignore next 5 */
if (process.argv[1] === fileURLToPath(import.meta.url)) {
const input = JSON.parse(readFileSync(0, 'utf8'));
const result = run(input);
if (result) process.stdout.write(JSON.stringify(result));
}