plugins/development-harness/skills/code-review-typescript/SKILL.md
Provides TypeScript-specific code review patterns covering strict mode, ESM, type safety, branded types, discriminated unions, async patterns, runtime safety, and common anti-patterns. Activates on detection of tsconfig.json, *.ts, or *.tsx files during code review — loaded automatically by dh:code-reviewer.
npx skillsauth add jamie-bitflight/claude_skills code-review-typescriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Stack-specific rules loaded by dh:code-reviewer when tsconfig.json, *.ts, or *.tsx files are detected.
tsconfig.json must enable strict: true — this covers noImplicitAny, strictNullChecks, strictFunctionTypes, and othersexactOptionalPropertyTypes: true is required in new projects — prevents undefined from being assigned to optional propertiesnoUncheckedIndexedAccess: true is required when indexing arrays or records — prevents silent undefined propagation@ts-ignore comment without an accompanying explanation comment is a blocking finding@ts-expect-error is preferred over @ts-ignore — it fails if the error goes awayany type without an explanatory comment is a blocking findingas SomeType) without runtime validation at the same boundary are a blocking findingunknown is the correct type for values from external sources — validate before narrowing, not afterobject as a type is not meaningful — use Record<string, unknown> or a specific interfacevalue!) without a comment explaining why null is impossible are a blocking findingisLoading, isError, isSuccess as separate booleans allows impossible combinations// WRONG: boolean flags allow impossible states
interface State {
isLoading: boolean;
isError: boolean;
data: User | null;
}
// RIGHT: discriminated union — impossible states are unrepresentable
type State =
| { status: "loading" }
| { status: "error"; error: Error }
| { status: "success"; data: User };
UserId and OrderId are both string at runtime — without brands, they are interchangeable to the type checkertype UserId = string & { readonly _brand: "UserId" };
type OrderId = string & { readonly _brand: "OrderId" };
function makeUserId(id: string): UserId {
return id as UserId;
}
require() calls are a blocking finding — use import syntaximport type must be used for type-only imports — prevents runtime errors and improves tree-shakingimport() must be typed with the expected module shapeawait or .then()/.catch()) are a blocking findingPromise.all is required for parallel independent async operations — sequential await in a loop is an anti-pattern when operations are independentawait inside a for loop that processes independent items is a blocking findingas UserType casts on external dataJSON.parse(text) as MyType is a blocking findingprocess.env.API_KEY! without validation is a blocking findingsatisfies Operatorsatisfies is preferred over explicit type annotations for config objects and record literals — preserves the literal type while validating against the declared type// RIGHT: satisfies preserves literal types
const config = {
port: 3000,
host: "localhost",
} satisfies ServerConfig;
// config.port is typed as 3000, not number
// WRONG: any without comment
function process(data: any) { ... }
// RIGHT: specific type or documented any
function process(data: unknown) {
if (!isUserEvent(data)) throw new TypeError("Expected UserEvent");
...
}
// WRONG: floating promise
sendMetrics(event);
// RIGHT: awaited or explicitly fire-and-forget
void sendMetrics(event); // intentionally not awaited — best-effort telemetry
// or
await sendMetrics(event);
development
When an application needs to store config, data, cache, or state files. When designing where user-specific files should live. When code writes to ~/.appname or hardcoded home paths. When implementing cross-platform file storage with platformdirs.
testing
Enforce mandatory pre-action verification checkpoints to prevent pattern-matching from overriding explicit reasoning. Use this skill when about to execute implementation actions (Bash, Write, Edit) to verify hypothesis-action alignment. Blocks execution when hypothesis unverified or action targets different system than hypothesis identified. Critical for preventing cognitive dissonance where correct diagnosis leads to wrong implementation.
tools
Reference guide for the Twelve-Factor App methodology — 15 principles (12 original + 3 modern extensions) for building portable, resilient, cloud-native applications. Use when evaluating application architecture, designing cloud-native services, reviewing codebases for methodology compliance, advising on configuration, scaling, observability, security, and deployment patterns. Incorporates the 2025 open-source community evolution and cloud-native reinterpretations of each factor.
tools
Converts user-facing documentation (how-to guides, tutorials, API references, examples) in any format — Markdown, PDF, DOCX, PPTX, XLSX, AsciiDoc, RST, HTML, Jupyter notebooks, man pages, TOML/YAML/JSON configs, and plain text — into Claude Code skill directories with SKILL.md plus thematically grouped references/*.md files. Use when given a docs directory or mixed-format documentation to transform into an AI skill. Uses MCP file-reader server for binary formats.