Agent skill

Typescript

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the…

MITAuto-check passedDatabases

Install Typescript

skills CLI
$ npx skills add ericrisco/rsc-harness --skill typescript -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness typescript --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/typescript .claude/skills/typescript && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
typescript
GitHub stars
156
Token cost
~2.8k tokens
SKILL.md length
928 words
Files
6 (incl. scripts, references)
Skills in repo
229
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the…

  • Works in 3 steps: Prefer inference; annotate boundaries.… → import type for type-only imports, with… → Narrow, don't cast. Reach for type…
  • Fixing TypeScript type code (.ts/.tsx/.d.ts)
  • SKILL.md covers Boundary: language vs runtime…, Decision rules, The type-system toolbox and tsconfig: strict base, plus 3 more sections
  • Runs Shell scripts from its folder; calls tsc and npx

What it does

Typescript is an agent skill from ericrisco/rsc-harness. Use when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the build toolchain. NOT runtime code, fs/streams/http (that is nodejs); NOT component/route typing (that is react/nextjs); NOT ORM type-gen (that is drizzle-orm).

Its SKILL.md is about 2.8k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/build-and-monorepo.md`).

It sits in Databases, covering Type safety, ORMs and data access and React components. It works with TypeScript, React, Node.js and Next.js. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Fixing TypeScript type code (.ts/.tsx/.d.ts)
  • Modeling data with generics/unions/branded types
  • Diagnosing narrowing failures
  • Configuring tsconfig and the build toolchain

Example prompts

  • “/typescript”

Requirements

  • Python 3
  • Node.js
  • A Bash shell

Workflow steps

3 steps, taken from the first numbered list in SKILL.md.

  1. Prefer inference; annotate boundaries. Let TS infer locals and returns; annotate
  2. import type for type-only imports, with verbatimModuleSyntax: true. Why: it
  3. Narrow, don't cast. Reach for type guards, in, typeof, discriminant checks before

What it can do on your machine

Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • tsc
    • npx

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npx, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Typescript loads about 2.8k tokens when it runs, and up to ~5.6k if it reads all its reference files. Until then it costs about 89 tokens; SKILL.md has 928 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~89
When it runs · the whole SKILL.md, loaded when a task matches
~2.8k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~5.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 928 words, ~2,762 tokens.

Download SKILL.mdSave it as .claude/skills/typescript/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
typescript
description
Use when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the build toolchain. NOT runtime code, fs/streams/http (that is `nodejs`); NOT component/route typing (that is `react`/`nextjs`); NOT ORM type-gen (that is `drizzle-orm`).
tags
typescript, types, generics, tsconfig, type-safety
recommends
nodejs, secure-coding, drizzle-orm
origin
risco

Idiomatic TypeScript types

Express data and contracts precisely in the TypeScript type system, and configure the compiler so the types actually hold.

Targets TypeScript 5.9 (current stable, Q1 2026): redesigned tsc --init defaults (module: nodenext, target: esnext, moduleDetection: force, strict on), import defer for deferred module evaluation, expandable editor hovers. The TypeScript 7 native compiler (tsgo, the Go port) is in preview as @typescript/native-preview and type-checks roughly 10x faster (VS Code's 1.5M LOC: 89s -> 8.74s) — adopt it for fast local checks; stable 7.0 lands early 2026.

Boundary: language vs runtime vs framework

Three layers, three owners. Language + compiler config lives here — generics, narrowing, .d.ts, tsconfig, and the build toolchain (tsc vs tsgo, tsx, resolution mode). Runtime behavior (how a stream backpressures, how the event loop schedules) is nodejs. Framework idioms (component props, route maps, server-component typing) are react/nextjs/nestjs — those borrow this skill's type mechanics but own their wiring. A tsconfig question is here; a "stream backpressure" question is nodejs; a "type my useReducer state" question is react. Also delegate: ORM schema-to-type generation -> drizzle-orm / prisma-orm; REST/contract shape design -> api-design; test runner and E2E setup -> testing-web / e2e-testing; injection/authz review -> secure-coding; Python typing -> python; Go -> go.

Decision rules

Apply these on every TypeScript edit:

  1. Prefer inference; annotate boundaries. Let TS infer locals and returns; annotate function parameters, public APIs, and .d.ts. Why: redundant annotations drift from reality and suppress the better inferred type.
  2. import type for type-only imports, with verbatimModuleSyntax: true. Why: it prevents emitting type-only imports as runtime requires and lets esbuild/swc transpile each file alone.
  3. Narrow, don't cast. Reach for type guards, in, typeof, discriminant checks before as; when as is unavoidable, only as <narrower> or as unknown as T at a true I/O boundary. Why: as asserts a claim the compiler cannot verify — it is a silenced error, and as to a wider or unrelated type is almost always a real bug hidden.

The type-system toolbox

Generics + constraints, and const type parameters

Constrain type parameters so callers get errors at the call site, and use a const type parameter (TS 5.0+) to preserve literal inference without as const everywhere:

ts
// Bad: unconstrained T, and the literal "a"|"b" widens to string.
function pick<T>(obj: T, key: string) { return (obj as any)[key]; }

// Good: K is constrained to obj's keys; const T keeps the literal union.
function pick<const T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
const r = pick({ a: 1, b: "x" } as const, "b"); // r: "x", not string
unknown over any at every boundary

any disables checking and silently poisons every downstream type it touches; unknown forces a narrow before use.

ts
// Bad: any flows everywhere, no error ever fires downstream.
function parse(json: string): any { return JSON.parse(json); }

// Good: unknown forces a narrow before the value is trusted.
function parse(json: string): unknown { return JSON.parse(json); }
const data = parse(input);
if (typeof data === "object" && data && "id" in data) { /* now narrowed */ }
satisfies for config validation without widening
ts
type Route = { path: string; method: "GET" | "POST" };

// Bad: annotation widens — routes.home.method is "GET" | "POST", and a typo in
// a key would only surface far away.
const a: Record<string, Route> = { home: { path: "/", method: "GET" } };

// Good: satisfies validates each entry AND keeps literal types.
const routes = {
  home: { path: "/", method: "GET" },
} satisfies Record<string, Route>;
routes.home.method; // "GET" (narrow), and "GE" would error right here
Discriminated unions + exhaustive never

Model state as a discriminated union, not an optional-field bag: { data?: T; error?: E; loading?: boolean } permits loading && error; a literal discriminant makes illegal states unrepresentable. That discriminant must be a literal type (not string), and you must check it before destructuring — destructuring first throws away the narrowing.

ts
type State =
  | { status: "loading" }
  | { status: "ok"; data: string }
  | { status: "error"; message: string };

// Bad: destructured before the check — `data`/`message` are typed as the union.
function render({ status, data, message }: State) { /* no narrowing */ }

// Good: switch on the literal discriminant, exhaustive never guard at the end.
function render(s: State): string {
  switch (s.status) {
    case "loading": return "...";
    case "ok": return s.data;
    case "error": return s.message;
    default: { const _exhaustive: never = s; return _exhaustive; }
  }
}

Add a "deleted" member to State and the default branch fails to compile — that is the point.

Branded (nominal) types

TS is structural, so a UserId and a raw string are interchangeable unless you brand them:

ts
type UserId = string & { readonly __brand: "UserId" };
const asUserId = (s: string): UserId => s as UserId; // brand only at the validated boundary
function load(id: UserId) { /* a bare string is now a compile error */ }
Utility types cheat row

Partial<T> Required<T> Readonly<T> Pick<T,K> Omit<T,K> Record<K,V> Exclude<U,M> Extract<U,M> NonNullable<T> ReturnType<F> Parameters<F> Awaited<T> NoInfer<T> (TS 5.4+, blocks a type param from inferring at one site).

Mapped / conditional / template-literal one-liners
ts
type Mutable<T> = { -readonly [K in keyof T]: T[K] };          // strip readonly
type Nullable<T> = { [K in keyof T]: T[K] | null };            // mapped transform
type Unwrap<T> = T extends Promise<infer U> ? U : T;           // conditional + infer
type EventName<T extends string> = `on${Capitalize<T>}`;       // template literal

Deep recipes (recursive types, declaration merging, variance/in-out, assertion functions, overloads) live in references/type-system.md.

tsconfig: strict base

Copy-paste base. Every package extends this and overrides only paths/references:

jsonc
{
  "compilerOptions": {
    "strict": true,                    // the whole strict family, non-negotiable
    "noUncheckedIndexedAccess": true,  // arr[i] / rec[k] are T | undefined
    "verbatimModuleSyntax": true,      // explicit import type; safe single-file transpile
    "isolatedModules": true,           // each file transpilable alone (esbuild/swc/babel)
    "skipLibCheck": true,              // don't type-check node_modules .d.ts (speed)
    "resolveJsonModule": true,         // import data.json with types
    "target": "esnext",
    "module": "nodenext",              // or "esnext" + "moduleResolution": "bundler"
    "moduleResolution": "nodenext",
    "moduleDetection": "force",
    "noEmit": true                     // a bundler/tsc -b emits; the base just checks
  }
}
Show full SKILL.md (401 more words)Show less
moduleResolution: bundler vs nodenext
Aspectbundlernodenext
Use whenVite / Next / Remix / esbuild build the codeCode runs directly in Node (no bundler)
Relative import extensionsomit (./util)required (./util.js)
package.json exports/importsresolvedresolved
module settingesnext/preservenodenext
Emits runnable JS itselfno (the bundler does)yes

Pick bundler when a bundler owns resolution; pick nodenext for libraries and scripts that Node executes directly. Field-by-field reference and the full matrix are in references/build-and-monorepo.md.

Monorepo & build

Use project references so packages type-check independently and in dependency order. A shared tsconfig.base.json holds the strict flags; each package extends it, sets composite: true, outDir/rootDir, and lists upstream packages under references. Build the graph with tsc -b (or tsgo -b).

For declaration emit and publishing a library, set declaration: true, declarationMap: true, and an exports map in package.json. For fast local checks prefer tsgo (TS7 preview: npx @typescript/native-preview); run scripts with tsx instead of ts-node. Depth, build-order graph, path aliases, and the tsgo adoption steps are in references/build-and-monorepo.md.

Anti-patterns

Anti-patternWhy it bitesDo instead
any as an escape hatchdisables all checking and spreads silently downstreamunknown + narrow, or a precise type / generic
as to silence "not assignable"asserts a claim TS can't verify — hides the real bugfix the type, or narrow with a guard/in/typeof
enum for a small fixed setemits runtime code, awkward with isolatedModules, no literal subtypingunion of string literals ("a" | "b") + as const
Destructure before the discriminant checknarrowing is lost; fields become the full unioncheck obj.kind first, then read fields
Skipping noUncheckedIndexedAccessarr[i]/rec[k] typed as T but are undefined at runtimeenable it; handle the | undefined
Function / bare object / {} typesaccept almost anything, no call-signature safetya precise signature, or Record<string, unknown>
No exhaustive never guard on unionsa new union member compiles with a missing branchdefault: const _: never = x in every switch
One giant tsconfig for a monorepocan't express per-package targets; breaks referencestsconfig.base.json + per-package extends
// @ts-ignoreswallows the error even after the line is fixed, masking new ones// @ts-expect-error (errors if the line later type-checks)
Default-importing in a CJS-emit file under verbatimModuleSyntaxblocked / wrong emituse export =/named, or set the right module

Project grounding

When working inside a real workspace, record this project's tsconfig and strictness choices (resolution mode, which strict flags are on, the build tool) in the project wiki via ../harness/SKILL.md — so the next session does not re-derive them.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/typescript of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/build-and-monorepo.md
  • references/type-system.md
  • scripts/verify.sh

Open the folder on GitHubat commit 92fde8f

Compare with similar skills

Typescript next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Typescript compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Typescript this skillericrisco/rsc-harness156—~2.8kAutomated safety check: PassMIT
Spiceflowremorses/spiceflow167—~1.9kAutomated safety check: PassMIT
Fetching Library Docsaiskillstore/marketplace4301 repos~1.6kAutomated safety check: PassNone
Spotpatchhuanglvjing/spotpatch134—~998Automated safety check: PassMIT
Drizzle Ormgrowupanand/ConvoForm1011 repos~2.7kAutomated safety check: PassApache-2.0
Drizzle Orm Expertdavila7/claude-code-templates32k3 repos~2.6kAutomated safety check: PassMIT

Similar skills

  • Spiceflow

    remorses/spiceflow

    Spiceflow is a super simple, fast, and type-safe API and React Server Components framework for TypeScript.

    167 GitHub stars~1.9k tokensUpdated today
    Backend & APIsAuto-check passed
  • Fetching Library Docs

    aiskillstore/marketplace

    Token-efficient library API documentation fetcher using Context7 MCP with 77% token savings.

    430 GitHub starsUsed in 1 repo~1.6k tokens
    DatabasesAuto-check passed
  • Spotpatch

    huanglvjing/spotpatch

    为 React 项目建立从浏览器页面元素到精确 JSX/TSX 源码、结构化上下文与可审阅修改的 SpotPatch 工作流。用户提到 SpotPatch、截图沟通前端修改、页面元素定位源码、Vite 或 Next.js 接入、组件数据链路、结构化 Prompt、AI 补丁审阅、安装检查或故障排查时使用此技能。

    134 GitHub stars~998 tokensUpdated 9 days ago
    Frontend & DesignAuto-check passed
  • Drizzle Orm

    growupanand/ConvoForm

    Type-safe SQL ORM for TypeScript with zero runtime overhead. An agent skill from growupanand/ConvoForm.

    101 GitHub starsUsed in 1 repo~2.7k tokens
    DatabasesAuto-check passed
  • Drizzle Orm Expert

    davila7/claude-code-templates

    Expert in Drizzle ORM for TypeScript — schema design, relational queries, migrations, and serverless database integration.

    32k GitHub starsUsed in 3 repos~2.6k tokens
    DatabasesAuto-check passed
  • Context7 Efficient

    aiskillstore/marketplace

    Token-efficient library documentation fetcher using Context7 MCP with 86.8% token savings through intelligent shell pipeline filtering.

    430 GitHub stars~1.5k tokensUpdated today
    DatabasesAuto-check passed

More from ericrisco/rsc-harness

All 229 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    156 GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    156 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    156 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    156 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    156 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    156 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Questions about Typescript

What does Typescript do?

A skill your agent uses when writing or fixing TypeScript type code (.ts/.tsx/.d.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the…. Typescript is an agent skill from ericrisco/rsc-harness.ts), modeling data with generics/unions/branded types, diagnosing narrowing failures, or configuring tsconfig and the build toolchain.

When should I use Typescript?

Typescript fits situations like: fixing TypeScript type code (.ts/.tsx/.d.ts); modeling data with generics/unions/branded types; diagnosing narrowing failures; configuring tsconfig and the build toolchain.

How do I install Typescript in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill typescript -a claude-code`. Or copy the skill folder (skills/typescript in ericrisco/rsc-harness) into .claude/skills/typescript in your project. Claude Code loads it when a task matches its description.

How do I install Typescript in Codex?

Run `npx skills add ericrisco/rsc-harness --skill typescript -a codex`. Or copy the skill folder (skills/typescript in ericrisco/rsc-harness) into .agents/skills/typescript in your project. Codex loads it when a task matches its description.

Can I use Typescript in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill typescript -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/typescript, .gemini/skills/typescript, .github/skills/typescript and .opencode/skills/typescript in your project.

What does Typescript need to run?

Going by SKILL.md and its folder, Typescript needs a shell for the scripts in its folder and the command-line tools its instructions call (tsc and npx). Our summary lists: Python 3; Node.js; A Bash shell.

Does Typescript access the network?

SKILL.md contains no URLs. Its commands use npx, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Typescript safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Typescript use?

Typescript is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Typescript use?

About 2.8k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 2.8k tokens, read only when the agent opens those files.

What are the alternatives to Typescript?

Skills that share tags, products or a category with Typescript: Spiceflow (remorses/spiceflow, 167 stars), Fetching Library Docs (aiskillstore/marketplace, 430 stars), Spotpatch (huanglvjing/spotpatch, 134 stars) and Drizzle Orm (growupanand/ConvoForm, 101 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Typescript?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.