From javascript
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.
npx claudepluginhub xobotyi/cc-foundry --plugin javascriptThis skill uses the workspace's default tool permissions.
<prerequisite>
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Types 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 | [${CLAUDE_SKILL_DIR}/references/generics.md] | Utility type tables, conditional/mapped type examples, infer, template literals |
| Narrowing, type guards, discriminated unions | [${CLAUDE_SKILL_DIR}/references/narrowing.md] | typeof/instanceof/in examples, exhaustive switch, type predicates, assertion fns |
| tsconfig options, module resolution, project setup | [${CLAUDE_SKILL_DIR}/references/configuration.md] | Base/strict/module configs, library setup, compiler directives, project structure |
| Branded types, overloads, class patterns, enums | [${CLAUDE_SKILL_DIR}/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 Decisionunknownunknownany (temporary, with comment)any (with comment){} Type{} means "any non-nullish value" — almost never what you want.
unknown → Everything (null, undefined, primitives, objects)object → Non-primitive, non-null values{} → Any non-nullish value (primitives included)Record<string, unknown> → Objects with string keysPrefer 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 ${CLAUDE_SKILL_DIR}/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
${CLAUDE_SKILL_DIR}/references/generics.md for distributive behavior, infer, modifier removal, and key remapping.
interface, type alias, union) → Always — default choicePartial, Pick, Omit, Record) → Well-known transformationsinfer chains) → Rarely — last resortStay 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 ${CLAUDE_SKILL_DIR}/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.