johnie/skills · Archived

typescript-engineer

Resolve TypeScript errors, eliminate `any`, and design complex types (generics, conditional, mapped, template literal, branded/opaque).

First seen May 29, 2026

Installation

$ npx skills add johnie/skills --skill typescript-engineer

Summary

  • Resolve TypeScript errors, eliminate `any`, and design complex types (generics, conditional, mapped, template literal, branded/opaque).
  • Use for type-inference problems, `infer` / `extends` questions, utility types (`Partial`, `Record`, `ReturnType`, `Awaited`, `NoInfer`), `satisfies`, function overloads, declaration merging, and strict-mode refactors.

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from johnie/skills.

npx skills add johnie/skills

Browse all from johnie/skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Also listed on

Alternate registries and mirrors of this skill.

Repository health

Stars 2
License MIT
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsBash(tsc *), Bash(npx tsc *), Bash(pnpm tsc *), Bash(pnpm exec tsc *), Read, Edit, Grep, Glob

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 8,347 B
  • docs SUMMARY.md 380 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 4 installs

SKILL.md

TypeScript Engineer

Type-level design, compiler-error diagnosis, and strict-safety refactoring. This skill routes the user's intent to a set of focused rule files in references/; don't try to answer from SKILL.md alone on anything non-trivial.

Reference files live in ${CLAUDESKILLDIR}/references/.

When NOT to use

  • Runtime validation — use Zod / io-ts / Valibot (separate concern; types won't validate unknown input at the boundary).
  • Refactors that change runtime behavior — this skill preserves behavior. If the change is behavioral, use a refactoring / testing skill.
  • Build tooling issues (tsc not found, wrong tsconfig paths, module resolution not finding files) — that's config, not type-level design.
  • JavaScript-only questions where types aren't involved.

Decision tree

Identify the user's goal first, then load the matching rule file on demand.

1. "Something doesn't compile / tsc is red"
   → start at references/error-diagnosis.md
   → then the rule file that matches the error category

2. "Design a type / API for X"
   → references/generics-basics.md (always the foundation)
   → then conditional-types.md / mapped-types.md / template-literal-types.md
     depending on whether you need branching, per-key transforms, or string ops

3. "Remove any / tighten types in this code"
   → references/type-narrowing.md (for input validation)
   → references/utility-types.md (for structural transforms)
   → references/generics-basics.md (when a function/class needs to be generic)

4. "Explain / teach concept X"
   → match X in the routing table below

Routing table

Match keywords in the user's request to load the right rule file.

Keyword / topic Rule file
as const, typeof, satisfies, enum alternative, derive types from values [as-const-typeof.md](references/as-const-typeof.md)
array element type, [number] index [array-index-access.md](references/array-index-access.md)
Partial, Record, Omit, Pick, ReturnType, Parameters, Awaited, NoInfer, utility type [utility-types.md](references/utility-types.md)
generic, constraint, extends, type parameter [generics-basics.md](references/generics-basics.md)
builder pattern, chainable, fluent API [builder-pattern.md](references/builder-pattern.md)
deep inference, const type parameter, preserve literal types, F.Narrow in old code [deep-inference.md](references/deep-inference.md)
conditional type, extends ? :, distribute [conditional-types.md](references/conditional-types.md)
infer, extract inner type [infer-keyword.md](references/infer-keyword.md)
template literal type, string manipulation at type level [template-literal-types.md](references/template-literal-types.md)
mapped type, in keyof, transform properties [mapped-types.md](references/mapped-types.md)
brand type, opaque type, nominal typing, validated ID [opaque-types.md](references/opaque-types.md)
narrowing, typeof, instanceof, in, discriminated union, type guard, is [type-narrowing.md](references/type-narrowing.md)
assertion function, asserts value is, validate-and-throw [assertion-functions.md](references/assertion-functions.md)
overload, multiple signatures [function-overloads.md](references/function-overloads.md)
type test, prove a type, assert a type, Expect, Equal, @ts-expect-error [type-testing.md](references/type-testing.md)
type error, diagnostic, ts(…), "not assignable" [error-diagnosis.md](references/error-diagnosis.md)
TS version, "which version added", 5.5 / 5.9 / 6 / 7, erasableSyntaxOnly, stableTypeOrdering, native compiler, no compiler API, upgrade broke my build [typescript-versions.md](references/typescript-versions.md)

Working style

  • Check the version. Read typescript in package.json (or run npx tsc --version) before recommending anything version-gated. TypeScript 5.5 infers type predicates and 5.8 can ban enum outright, so the same advice is right or wrong depending on the target. [typescript-versions.md](references/typescript-versions.md) lists what changed.
  • Reproduce first. Run tsc --noEmit on the user's code before proposing a fix so you're reasoning about the real error, not a guess. Since 7.0 the compiler is a native binary and whole-project checks are fast — prefer a real run over reasoning from a snippet.
  • Simplest type that works. Don't reach for conditional/mapped/template-literal machinery when a plain generic or utility type would do. Complexity has a cost to everyone who reads the code later.
  • Validate type-level code. Use the Expect<Equal<A, B>> pattern (or similar) to prove the types are what you claim — see [type-testing.md](references/type-testing.md). Types that compile but are wrong are worse than runtime bugs — they silently lie.
  • Explain why the type works. Dense types are hard to read; a one-line comment naming the technique (// distributive conditional over UnionKey) pays for itself.

One snippet per category

These are smell-tests — read them, then jump to the reference file for the full pattern.

Eliminate any with a generic

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
// getProperty({ name: "Alice" }, "name") → inferred as string

See [generics-basics.md](references/generics-basics.md).

Narrow an unknown response at the boundary

function isUser(value: unknown): value is { id: number; name: string } {
  return (
    typeof value === "object" &&
    value !== null &&
    "id" in value &&
    "name" in value
  );
}

Two things to flag when you write one of these. in proves the keys exist but says nothing about their types, so the annotation is a promise the body doesn't keep — if the shape arrives over the network, validate it with Zod/Valibot instead. And on TS 5.5+ a guard like this often doesn't need the annotation at all; see [typescript-versions.md](references/typescript-versions.md).

See [type-narrowing.md](references/type-narrowing.md) and [assertion-functions.md](references/assertion-functions.md).

Preserve literals while enforcing shape

const palette = {
  red: [255, 0, 0],
  green: [0, 255, 0],
} as const satisfies Record<string, readonly [number, number, number]>;
// palette.red → readonly [255, 0, 0]

See [as-const-typeof.md](references/as-const-typeof.md).

Reference map

Core patterns — [as-const-typeof](references/as-const-typeof.md) · [array-index-access](references/array-index-access.md) · [utility-types](references/utility-types.md)

Generics — [generics-basics](references/generics-basics.md) · [builder-pattern](references/builder-pattern.md) · [deep-inference](references/deep-inference.md)

Type-level programming — [conditional-types](references/conditional-types.md) · [infer-keyword](references/infer-keyword.md) · [template-literal-types](references/template-literal-types.md) · [mapped-types](references/mapped-types.md)

Safety — [opaque-types](references/opaque-types.md) · [type-narrowing](references/type-narrowing.md) · [assertion-functions](references/assertion-functions.md) · [function-overloads](references/function-overloads.md)

Debugging — [error-diagnosis](references/error-diagnosis.md) · [type-testing](references/type-testing.md) · [typescript-versions](references/typescript-versions.md)