TypeScript type system, strict mode, and TS-specific patterns beyond JavaScript fundamentals. Invoke whenever task involves any interaction with TypeScript code — writing, reviewing, refactoring, debugging .ts/.tsx files, type definitions, generics, narrowing, tsconfig, or type-level programming.
Applies advanced TypeScript type safety, generics, and strict mode conventions for writing, reviewing, and refactoring code.
npx claudepluginhub xobotyi/cc-foundryThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/configuration.mdreferences/generics.mdreferences/narrowing.mdreferences/patterns.mdTypes encode intent. Let the compiler prove the rest.
TypeScript's value is in catching bugs at compile time. Write types that express your
domain; let inference handle the obvious. Never fight the type system — if you need as
or any, the types are wrong.
| Topic | Reference | Contents |
|---|---|---|
| Generics, utility types, type-level programming | references/generics.md | Utility type tables, conditional/mapped type examples, infer, template literals |
| Narrowing, type guards, discriminated unions | references/narrowing.md | typeof/instanceof/in examples, exhaustive switch, type predicates, assertion fns |
| tsconfig options, module resolution, project setup | references/configuration.md | Base/strict/module configs, library setup, compiler directives, project structure |
| Branded types, overloads, class patterns, enums | references/patterns.md | Interface vs type examples, assertion patterns, enum anti-patterns, callback types |
strict: true always. No exceptions. It enables strictNullChecks,
noImplicitAny, strictFunctionTypes, and other critical checks.unknown over any. Use unknown and narrow with type guards. any disables
type checking entirely. Reserve any for migration or test mocks only — document why.!) without justification. Prefer narrowing. If ! is
truly needed, add a comment explaining why the value cannot be null.as) for object literals. Use type annotations (: Foo)
instead — assertions hide missing/extra property errors.unknown vs any Decision| Situation | Use |
|---|---|
| Value from external source (API, JSON.parse, user input) | unknown |
| Function accepts anything, passes through without touching | unknown |
| Migrating JS to TS incrementally | any (temporary, with comment) |
| Test mock that intentionally bypasses type checking | any (with comment) |
{} Type{} means "any non-nullish value" — almost never what you want.
| Type | Allows |
|---|---|
unknown | Everything (null, undefined, primitives, objects) |
object | Non-primitive, non-null values |
{} | Any non-nullish value (primitives included) |
Record<string, unknown> | Objects with string keys |
Prefer unknown for opaque values, Record<string, unknown> for dict-like objects,
object when you need "any non-primitive".
const x: number = 5 or
const s: string = "hello". The compiler infers these correctly.import type for type-only imports. Enforced by verbatimModuleSyntax.
Use export type for type re-exports — required for isolatedModules.interface for object shapes. Better error messages, IDE support, and performance.type for everything else — unions, intersections, tuples, function types,
mapped/conditional types.interface. Everything else?
type. Pick one pattern per kind and stay consistent within a project.namespace. Use ES modules. namespace is legacy.string not String, number not Number.? over | undefined for fields and parameters. | undefined
forces callers to pass undefined explicitly.null/undefined in type aliases. Keep nullability at the use site:
function getUser(): User | null not type MaybeUser = User | null.!= null checks both null and undefined (the one valid == use).
?. for optional access. ?? for defaults.T is fine for
single-parameter generics; use TKey, TValue, TItem for multiple parameters.extends when possible. <T extends string> is better
than <T> if T must be a string.<T extends Record<string, unknown>> is better
than <T extends object> when you need string keys.identity("hello") not identity<string>("hello").<T, K extends keyof T> to relate parameters.interface Container<T, U = T[]> — omitted type args
fall back to the default.NoInfer<T> (TS 5.4+) prevents a parameter from being an inference site — use when
a parameter should be constrained by other params, not drive inference.Prefer built-in utility types over hand-rolling equivalents. Key types: Partial,
Pick, Omit, Record, Exclude, Extract, ReturnType, Parameters, Awaited,
NoInfer. Use explicit interfaces when the type represents a distinct domain concept.
See references/generics.md for the full catalog and usage guidance.
Conditional types (T extends U ? X : Y), mapped types ({ [P in keyof T]: ... }),
and template literal types (`${T}Changed`) are advanced tools — use for library
code and framework types. See references/generics.md for distributive behavior,
infer, modifier removal, and key remapping.
| Tier | Tools | Use When |
|---|---|---|
| Simple | interface, type alias, union | Always — default choice |
| Moderate | Partial, Pick, Omit, Record | Well-known transformations |
| Advanced | Conditional, mapped, template literal | Library code, framework types |
| Expert | Recursive types, complex infer chains | Rarely — last resort |
Stay at the lowest tier that solves your problem. If you can't explain what a type does in one sentence, it's too complex — split it, simplify it, or use explicit interfaces.
kind or type literal
field to each variant.default: { const _exhaustive: never = value; return _exhaustive; } to catch unhandled variants at compile time.function isFish(pet: Animal): pet is Fish.
Use when filtering arrays or in multiple call sites.function assertIsError(value: unknown): asserts value is Error — use for validation at boundaries.typeof, instanceof, in — use JavaScript narrowing constructs; TypeScript
understands them natively.typeof null === "object" pitfall. Always check for null separately before
typeof object checks.in operator and optional properties: if Human has swim?, "swim" in animal
narrows to Fish | Human, not just Fish."", 0, NaN, false. Prefer explicit
null checks over truthiness when these values are valid.x === y narrows both to their common type. != null checks
both null and undefined.type Status = "active" | "inactive" is simpler than enum Status.level !== Level.NONE, not
!!level. Numeric enum value 0 is falsy.: Foo catches errors; as Foo hides them.as syntax, never angle brackets (<Foo>value) — angle brackets
conflict with JSX.JSON.parse, DOM API returning wider types, trusted external sources.unknown: value as unknown as Foo. Never use any
as the intermediate type.public — it's the default. Only use public on non-readonly constructor
parameter properties.private for internal state, protected for subclass access.readonly on properties never reassigned after construction.constructor(private readonly db: Database) {}.private count = 0.override keyword on overridden methods (noImplicitOverride).void return for callbacks whose return value is ignored.(data: unknown, elapsed: number) => void not (data: unknown, elapsed?: number) => any.Use branded types for nominal-like safety when structural typing is too permissive:
domain IDs (UserId vs OrderId), validated strings (Email), units (Meters vs
Kilometers). Pattern: type UserId = string & { readonly __brand: unique symbol }.
Keep the branding mechanism consistent across the project — unique symbol is most
robust.
Use T[] for simple element types (string[], User[]). Use Array<T> for complex
element types (Array<string | number>). Same rule applies to readonly variants.
strict: true always. Non-negotiable. Also enable noUncheckedIndexedAccess
and noImplicitOverride.module: "NodeNext" when transpiling with tsc;
module: "preserve" with external bundlers (Vite, esbuild, Bun). Use
verbatimModuleSyntax: true in both cases.es2022 (stable). Set lib to include dom for browser projects.@ts-ignore. Use @ts-expect-error in tests only, with a comment.
Never @ts-nocheck in production.tsconfig.json minimal. Use extends for shared configs. Separate
tsconfig.build.json for builds (excludes tests, scripts).See references/configuration.md for the full options catalog, library project setup,
and project structure guidance.
When writing TypeScript code:
When reviewing TypeScript code:
The javascript skill is a hard prerequisite. The JavaScript skill governs code patterns; this skill governs type-level choices.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.
Create beautiful visual art in .png and .pdf documents using design philosophy. You should use this skill when the user asks to create a poster, piece of art, design, or other static piece. Create original visual designs, never copying existing artists' work to avoid copyright violations.