typescript-effective
Use when writing production TypeScript — clean code idioms, effective-TS items, strict tsconfig, migration from JS, build performance, testing, and anti-patterns. Load references/typescript-mastery.md for type-system depth and references/typescript-design-patterns.md for GoF patterns.
Best use case
typescript-effective is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Use when writing production TypeScript — clean code idioms, effective-TS items, strict tsconfig, migration from JS, build performance, testing, and anti-patterns. Load references/typescript-mastery.md for type-system depth and references/typescript-design-patterns.md for GoF patterns.
Teams using typescript-effective should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/typescript-effective/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How typescript-effective Compares
| Feature / Agent | typescript-effective | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Use when writing production TypeScript — clean code idioms, effective-TS items, strict tsconfig, migration from JS, build performance, testing, and anti-patterns. Load references/typescript-mastery.md for type-system depth and references/typescript-design-patterns.md for GoF patterns.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
SKILL.md Source
# Effective TypeScript
Acknowledgement: Shared by Peter Bamuhigire, techguypeter.com, +256 784 464178.
<!-- dual-compat-start -->
## Use When
- Use when writing production TypeScript — clean code idioms, effective-TS items, strict tsconfig, migration from JS, build performance, testing, and anti-patterns. Load `references/typescript-mastery.md` for type-system depth and `references/typescript-design-patterns.md` for GoF patterns.
- The task needs reusable judgment, domain constraints, or a proven workflow rather than ad hoc advice.
## Do Not Use When
- The task is unrelated to `typescript-effective` or would be better handled by a more specific companion skill.
- The request only needs a trivial answer and none of this skill's constraints or references materially help.
## Required Inputs
- Gather relevant project context, constraints, and the concrete problem to solve; load `references` only as needed.
- Confirm the desired deliverable: design, code, review, migration plan, audit, or documentation.
## Workflow
- Read this `SKILL.md` first, then load only the referenced deep-dive files that are necessary for the task.
- Apply the ordered guidance, checklists, and decision rules in this skill instead of cherry-picking isolated snippets.
- Produce the deliverable with assumptions, risks, and follow-up work made explicit when they matter.
## Quality Standards
- Keep outputs execution-oriented, concise, and aligned with the repository's baseline engineering standards.
- Preserve compatibility with existing project conventions unless the skill explicitly requires a stronger standard.
- Prefer deterministic, reviewable steps over vague advice or tool-specific magic.
## Anti-Patterns
- Treating examples as copy-paste truth without checking fit, constraints, or failure modes.
- Loading every reference file by default instead of using progressive disclosure.
## Outputs
- A concrete result that fits the task: implementation guidance, review findings, architecture decisions, templates, or generated artifacts.
- Clear assumptions, tradeoffs, or unresolved gaps when the task cannot be completed from available context alone.
- References used, companion skills, or follow-up actions when they materially improve execution.
## Evidence Produced
| Category | Artifact | Format | Example |
|----------|----------|--------|---------|
| Correctness | Strict tsconfig + Zod boundary register | Markdown doc covering strictness flags applied and Zod schemas at module boundaries | `docs/ts/strict-config-register.md` |
## References
- Use the `references/` directory for deep detail after reading the core workflow below.
<!-- dual-compat-end -->
Production-grade TypeScript beyond the type system. Every rule here lifts real code quality, not just appeases the compiler.
**Prerequisite:** Load `references/typescript-mastery.md` for type-system depth. Use this skill for day-to-day production idioms.
## When this skill applies
- Code review on TypeScript PRs.
- Starting a new TypeScript project (tsconfig, linting, test setup).
- Migrating a JavaScript codebase to TypeScript gradually.
- Eliminating "any" drift in an existing TS codebase.
- Tuning TypeScript build for large monorepos.
## Non-negotiables
1. `strict: true` plus `noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`, `noImplicitOverride`.
2. Never use `any`. Use `unknown` at boundaries and narrow.
3. Never cast with `as` unless there is no better option; never `as unknown as T`.
4. Validate every external input with Zod (API responses, env vars, form data, queue payloads).
5. Prefer `union` types over `enum` unless integer values and bidirectional lookup are needed.
6. Use discriminated unions with exhaustive `switch` and `assertNever`.
7. Never throw strings. Throw `Error` subclasses.
8. Model absence with `null`/`undefined` intentionally — don't mix.
9. `readonly` on inputs by default.
10. Error handling — prefer Result/Either for expected failures at boundaries.
## tsconfig for production
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true,
"noImplicitOverride": true,
"noFallthroughCasesInSwitch": true,
"noImplicitReturns": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"useUnknownInCatchVariables": true
}
}
```
`strict` alone is not enough. `noUncheckedIndexedAccess` catches real bugs (arr[i] is T | undefined). `exactOptionalPropertyTypes` distinguishes `{ x?: number }` from `{ x?: number | undefined }`. See `references/tsconfig-production.md`.
## Core effective-TS items
**Prefer types that narrow your values:**
```ts
// BAD - primitive obsession
function sendEmail(to: string, subject: string, body: string) { ... }
// GOOD - branded types
type Email = string & { readonly __brand: "Email" };
type Subject = string & { readonly __brand: "Subject" };
function parseEmail(raw: string): Email | null { ... }
```
**Discriminated unions + exhaustive match:**
```ts
type Event =
| { kind: "login"; userId: string }
| { kind: "logout"; userId: string; at: Date }
| { kind: "purchase"; userId: string; amount: number };
function handle(e: Event): string {
switch (e.kind) {
case "login": return `login ${e.userId}`;
case "logout": return `logout ${e.userId}`;
case "purchase": return `bought ${e.amount}`;
default: return assertNever(e);
}
}
function assertNever(x: never): never { throw new Error(`unhandled: ${JSON.stringify(x)}`); }
```
**Narrow `unknown` before use — never silently trust it.**
See `references/effective-ts-items.md` for the full catalogue (~40 items).
## Clean code in TS
- **Small functions** — one reason to change. Functions over 40 lines or 3 levels of nesting: split.
- **Names carry intent** — `isActive(user)` not `check(user)`; `loadUser(id)` not `get(id)`.
- **Comments explain WHY** — TS types explain WHAT. Don't duplicate.
- **SOLID in TS** — Single Responsibility, Interface Segregation, Dependency Inversion via constructor injection or factory functions.
- **Immutability** — `readonly`, `as const`, `Readonly<T>`, spread instead of mutate.
- **Pure functions where possible** — easier to test, reason about, memoise.
See `references/clean-code-ts.md`.
## Error handling — Result/Either at boundaries
Throwing is fine inside a module; at boundaries (API handlers, workers, UI event handlers), return typed results:
```ts
type Ok<T> = { ok: true; value: T };
type Err<E> = { ok: false; error: E };
type Result<T, E> = Ok<T> | Err<E>;
const ok = <T>(value: T): Ok<T> => ({ ok: true, value });
const err = <E>(error: E): Err<E> => ({ ok: false, error });
async function loadUser(id: string): Promise<Result<User, "not_found" | "db_down">> {
try {
const user = await db.user.findUnique({ where: { id } });
return user ? ok(user) : err("not_found");
} catch {
return err("db_down");
}
}
```
Libraries: `neverthrow`, `ts-results`, or hand-roll as above. Pick one per project. See `references/error-handling-result.md`.
## Zod at boundaries
Every external input parsed with Zod, every internal type inferred from the schema.
```ts
import { z } from "zod";
const UserCreate = z.object({
email: z.string().email(),
age: z.number().int().min(0).max(150),
role: z.enum(["admin", "member", "viewer"]),
}).strict();
type UserCreate = z.infer<typeof UserCreate>;
app.post("/users", (req, res) => {
const parsed = UserCreate.safeParse(req.body);
if (!parsed.success) return res.status(400).json({ errors: parsed.error.flatten() });
// parsed.data is fully typed
});
```
Sources of truth: Zod schema → inferred type. Never define the type separately. See `references/zod-boundaries.md`.
## Migration JS → TS
Gradual, not big-bang. See `references/migration-js-to-ts.md` for the playbook. Summary:
1. `allowJs: true`, `checkJs: true` — TS checks JS files.
2. Add JSDoc types as light annotation.
3. Rename `.js` → `.ts` file by file, fix errors.
4. Turn on `noImplicitAny`, then `strict`, then stricter flags one at a time.
5. Never convert in a single PR more than one team can review.
## Build performance
- **Project references** for monorepos — incremental builds across packages.
- **`isolatedModules`** lets bundlers type-check per-file.
- **`transpile-only`** in dev (ts-node with swc/esbuild, tsup).
- **Type-check in CI** separately from bundling.
- **Skip lib check** (`skipLibCheck: true`) — trust dep types.
See `references/build-performance.md`.
## Testing
- **vitest** for Node + browser — fast, Jest-compatible, TypeScript-native.
- **Type tests** with `expectTypeOf` (vitest) or `tsd` for library APIs.
- **Property-based tests** with `fast-check` for pure logic.
- **Fixtures** strongly typed via schemas — reuse Zod schemas for test data generators.
See `references/testing-vitest.md`.
## Anti-patterns
- `any` — signals "I give up on types." Fix, don't paper over.
- `as T` (type assertion) — silently lies to the compiler.
- `as unknown as T` — the double lie. Always wrong.
- `!` non-null assertion — use narrowing or a type guard.
- `Function` type — use `(...args: never[]) => unknown` or specific signatures.
- `Object` / `{}` type — use `Record<string, unknown>` or a specific shape.
- `enum` for small string sets — use union of string literals.
- Class with all static methods — use a namespace-less module.
- `namespace` — use ES modules.
- Parameter properties in class constructors where they hurt readability.
- Silent `catch (e) {}` — log or re-throw.
- Mutating function arguments.
- `delete obj.key` on typed objects — use spread to build a new object.
See `references/anti-patterns.md`.
## CI gates
```text
tsc --noEmit
eslint . --max-warnings=0
vitest run --coverage --coverage.thresholds.lines=80
```
## Read next
- `references/typescript-mastery.md` — deep type system when you need it.
- `references/typescript-design-patterns.md` — GoF patterns in TS.
- `typescript-full-stack` — shared types FE↔BE, Zod everywhere.
- `react-development` / `nextjs-app-router` — framework-specific.
## References
- `references/tsconfig-production.md`
- `references/effective-ts-items.md`
- `references/clean-code-ts.md`
- `references/error-handling-result.md`
- `references/zod-boundaries.md`
- `references/migration-js-to-ts.md`
- `references/build-performance.md`
- `references/testing-vitest.md`
- `references/anti-patterns.md`Related Skills
typescript-full-stack
Use when building end-to-end TypeScript applications — Node backend (Fastify), React/Next frontend, shared types via tRPC or Zod, monorepo with turborepo/nx, Prisma/Drizzle data layer, end-to-end type safety.
web-app-security-audit
Use when auditing a PHP/JavaScript/HTML web application for security vulnerabilities. Covers configuration, authentication, authorization, input validation, XSS, API security, HTTP headers, and dependency scanning. Produces a severity-rated audit...
vibe-security-skill
Use when designing or reviewing security for a web application, API, or multi-tenant SaaS — produces threat model, abuse case list, auth/authz matrix, and secret handling plan; covers OWASP Top 10 2025 and the AI-code-generation blind spots. Neighbours — api-design-first owns auth model fields, deployment-release-engineering owns secret rotation choreography, ai-security and llm-security own model-specific threats.
network-security
Use when designing, hardening, or auditing network-layer security for self-managed Debian/Ubuntu SaaS infrastructure — firewalls (nftables/UFW), WAF (ModSecurity + OWASP CRS), VPN (WireGuard, OpenVPN, IPsec), TLS/PKI ops, IDS/IPS (Suricata, Fail2ban), zero-trust, SSH hardening, DDoS mitigation, DNS security. Complements web-app-security-audit (app layer) and cicd-devsecops (secrets/CI).
linux-security-hardening
Use when hardening a Debian/Ubuntu server — user/group/sudo hardening, file permission audits, PAM password policy + MFA, AppArmor mandatory access control, auditd system call logging, kernel sysctl hardening, file integrity monitoring (AIDE), rootkit detection (rkhunter/chkrootkit), unattended security patching, GRUB + UEFI + LUKS boot security, and CIS benchmark compliance.
dpia-generator
Generate a Data Protection Impact Assessment (DPIA), Uganda DPPA 2019-compliant. Use when producing or reviewing a data protection impact assessment, a privacy impact assessment, when uganda-dppa-compliance flags [DPIA-REQUIRED], or when processing large-scale or sensitive personal data for a new feature.
code-safety-scanner
Scan any codebase for 14 critical safety issues across security vulnerabilities, server stability (500 errors), and payment misconfigurations. Use when auditing code before deployment, reviewing AI-generated code for production readiness, or...
world-class-engineering
Use when designing, building, reviewing, or upgrading production software systems that must be secure, performant, maintainable, scalable, and user-centered. Apply before writing specs, code, architecture, APIs, databases, mobile apps, SaaS platforms, or ERP systems.
update-Codex-documentation
Update project documentation files (README.md, PROJECT_BRIEF.md, TECH_STACK.md, ARCHITECTURE.md, docs/API.md, docs/DATABASE.md, AGENTS.md, docs/plans/NEXT_FEATURES.md) when significant changes occur. MANDATORY at end of each work session to...
skill-writing
Use when creating or upgrading skills in this repository. Covers repository-specific frontmatter rules, progressive disclosure, reference-file strategy, validation, and the quality bar required for production-grade engineering skills.
skill-safety-audit
Scan new or updated skills for unsafe or malicious instructions (unknown tools, external installers, credential harvesting) before accepting them into the repository.
skill-composition-standards
Use when authoring a new skill, normalising an older skill, or reviewing a skill PR — defines the repository-wide house style (frontmatter, decision rules, anti-patterns, references), the output contracts each baseline-skill type must produce, and the input contracts each specialist skill must declare. This is the enforcement spine that makes the repository compose as a system, not a library of linked documents.