About typescript
A router-style skill for JavaScript and TypeScript developers, with project-aware guidance and on-demand references for language features, runtimes, design, and testing. It also collects coding rules and recommendations for TypeScript at scale.
Key features
- 01Routes topics to focused references
- 02Project configuration-first guidance
- 03JavaScript and TypeScript coding rules
- 04TypeScript-at-scale recommendations
- 05Error-handling strategy guidance
Use cases
- 01Choose a reference for a TypeScript language question
- 02Apply consistent rules in an existing codebase
- 03Review error handling and type boundaries
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ bsene/ skills --skill typescriptAfter installing, type/typescriptin Claude Code to confirm it loaded.
Bundled files
References and scripts installed along with SKILL.md.
run-history.mdcomposition/references/currying-and-point-free.mdmonoids.mdobject-composition-and-factories.mdpure-functions-and-composition.mdreferences/deno.mddomain-modeling-functional.mdes-features-by-edition.mdjs-pitfalls-and-idioms.mdjs-runtime-mechanics.mdnode-patterns.mdtotal-typescript.mdts-language-gaps.mdrules/avoid-intermediate-arrays.mdavoid-type-assertions.mdexplicit-return-types.mdfavor-existing-types-over-as-const.mdjs-general-conventions.mdjs-interop-declarations.mdmodule-organization.mdno-barrel-files.mdno-interface-prefix.mdnull-undefined.mdprefer-explicit-context-over-this.mdreadonly.mdtype-system/references/benchmarks.mddeclarations-and-style.mdillegal-states-and-exhaustiveness.mdstructural-typing-and-branding.mdDetails
From the project READMEJavaScript & TypeScript
Primary reference: TypeScript docs. Rule files below link to the specific docs section they encode; when a rule and the official docs disagree, the docs win and the rule should be updated.
Follow the project
Use the repository's configured runtime, imports, test runner, and verification commands. Read its agent instructions and configuration before changing tooling or introducing a workflow.
Route to Sub-skills
type-system/ and zod/ are reference bundles read on demand from this router — they are not independently discovered skills, so their own frontmatter is intentionally minimal (no duplicate trigger list needed).
→ Type system (unknown/any, narrowing, discriminated unions, mapped types…) → type-system/SKILL.md
→ Total TypeScript / Matt Pocock (type derivation, satisfies, generic inference, NoInfer, distributivity, type tests) → references/total-typescript.md
→ Zod (schema validation, transforms, coercion, branded types…) → zod/SKILL.md
→ Functional composition (pipe/compose, currying, pure functions, factories, functional mixins, monoids…) → composition/SKILL.md
→ Node.js design patterns (async control flow, streams, EventEmitter, DI, batching, workers, scaling) → references/node-patterns.md
→ JS runtime mechanics (this, closures, prototypes, generators, event-loop order, promises) → references/js-runtime-mechanics.md
→ JS pitfalls & idioms (coercion, dictionaries, array/iteration, API design, async discipline, surviving patterns) → references/js-pitfalls-and-idioms.md
→ ES features by edition (ES2015–ES2025 additions, modern replacements, target/lib guidance) → references/es-features-by-edition.md
→ Domain modeling (workflows as pipelines, state machines by type, Result errors, DTO boundaries, persistence at the edges) → references/domain-modeling-functional.md
→ TS language gaps (variance, overloads, assertion functions, module resolution, type-driven design) → references/ts-language-gaps.md
→ Deno runtime (runtime sunset notice; maintain existing projects only: configuration, permissions, dependencies, HTTP, tests, Node compatibility) → references/deno.md
→ Design patterns (Strategy, Factory, Builder, Decorator, Mixin…) → object-oriented-programming skill
→ SOLID principles (SRP, OCP, LSP, ISP, DIP) → object-oriented-programming skill
→ Testing (unit tests, mocks vs stubs, brittle tests, test pyramid) → testing skill
Error Handling
| Strategy | Caller forced to handle? | Composability |
|---|---|---|
Return T | null | Yes (null check) | Low |
| Throw exception | No — easy to miss | High |
Return exception T | ErrorA | ErrorB | Yes — union exhaustion | Medium |
| Option/Either type | Via .flatMap chain | High (needs library) |
Return exceptions (preferred for expected failures):
class BadRequestError extends Error {
readonly status = 400 as const;
}
class UnauthorizedError extends Error {
readonly status = 401 as const;
}
class NotFoundError extends Error {
readonly status = 404 as const;
}
function resolveUser(
token: string,
id: string,
): User | BadRequestError | UnauthorizedError | NotFoundError {
if (!id.trim()) return new BadRequestError("Missing user ID");
if (!isValidJwt(token)) return new UnauthorizedError("Invalid token");
const user = userStore.get(id);
if (!user) return new NotFoundError(`User ${id} not found`);
return user;
}
const result = resolveUser(authHeader, userId);
if (result instanceof BadRequestError) res.status(400).send(result.message);
else if (result instanceof UnauthorizedError)
res.status(401).send(result.message);
else if (result instanceof NotFoundError) res.status(404).send(result.message);
else res.status(200).json(result);
TypeScript at Scale
- Enable
"strict": trueglobally; enforce in CI (Compiler Options); layer on the flags not included in strict:noUncheckedIndexedAccess,noImplicitReturns,noFallthroughCasesInSwitch,noUnusedLocals,noUnusedParameters - Use
@ts-expect-errorover@ts-ignore - Track
anyusage via@typescript-eslint/no-explicit-any - Keep API/DTO types separate from domain types — map at boundaries (example below)
- Validate external inputs (API bodies, env vars, queues) with Zod at boundaries (example:
zod/SKILL.md) - Publish domain contracts as
@org/contracts; use project references for boundaries (Project References)
Read On Demand
- Effect TS — use the official documentation for typed errors, concurrency, resource management, and dependency requirements. Match the documentation version to the project's installed
effectversion before using API examples. - Domain vs. DTO mapping example — DTO shape never leaks into the domain:
export type UserDTO = {
user_id: string;
display_name: string;
created_at: string;
};
export type User = { id: string; name: string; createdAt: Date };
export function toDomain(dto: UserDTO): User {
return {
id: dto.user_id,
name: dto.display_name,
createdAt: new Date(dto.created_at),
};
}
- Zod boundary-validation example:
zod/SKILL.md. - Node.js runtime topics (event loop/libuv, core modules, CJS/ESM, debugging & profiling, HTTP ecosystem, npm/packaging, security): see the free ebook "Become a Node.js developer" (online). Note: French edition is complete; English edition is partial.
- ECMAScript edition history (ES1 1997 → ES2025): see MDN's JavaScript editions timeline. Use when judging which edition first shipped a feature, what needs a polyfill on older runtimes, which syntax is safe for a target environment, or choosing
tsconfigtarget/lib.
Rules (JavaScript & TypeScript, always apply)
JavaScript foundation
| Rule | File |
|---|---|
| Use JavaScript general conventions (naming, const/let, destructuring, template literals) | rules/js-general-conventions.md |
Prefer explicit context (params) over implicit this | rules/prefer-explicit-context-over-this.md |
Do not use barrel files (index.js/index.ts re-exports) | rules/no-barrel-files.md |
Avoid intermediate arrays on hot paths (filter().map() chains) | rules/avoid-intermediate-arrays.md |
undefined for absence, null for API/external contracts | rules/null-undefined.md |
TypeScript-specific
| Rule | File |
|---|---|
Avoid type assertions (as T, !, as unknown as T) | rules/avoid-type-assertions.md |
Favor existing types over as const | rules/favor-existing-types-over-as-const.md |
Do not prefix interfaces with I | rules/no-interface-prefix.md |
Mark properties and arrays readonly to signal immutability | rules/readonly.md |
Infer obvious local returns; annotate public APIs and risky inference; enable noImplicitAny | rules/explicit-return-types.md |
| Use modules instead of namespaces; prefer named exports | rules/module-organization.md |
Prefer shipped types / @types/*; otherwise add a minimal .d.ts | rules/js-interop-declarations.md |
Benchmark
This router has no scenario of its own. Gate data lives in the leaf footers:
type-system/SKILL.md→## Benchmark(scenariostypescript-001PASS andtypescript-002SOFT PASS, run 2026-08-31).composition/SKILL.md→## Benchmark(scenariocomposing-software-001, run 2026-08-31, PASS).- Historical optimizer runs:
run-history.md(includes per-skill gate targets).
Gate per .agents/skills/skill-optimizer/rules/release-gates.md.