agentsclimarketplace

Typescript

Skill crustacean-dev/stack-guardrails/skills/typescript

Enforces strict TypeScript guardrails whenever writing, reviewing, refactoring, or generating .ts/.tsx/.mts/.cts code. Applies automatically to any TypeScript task — creating functions, components, types, configs, utility libraries, or converting JS to TS. Catches violations like enum (use as const), any (use unknown), default exports, barrel files, empty catch blocks, var, @ts-ignore, missing return types, and non-readonly properties. Also triggers for tsconfig changes, React/JSX with TypeScript props, API clients, CLI tools, and code reviews mentioning type safety. If the file extension or code context is TypeScript, use this skill — even if the user doesn't say 'TypeScript' explicitly.From its SKILL.md

Install
npx -y skills add crustacean-dev/stack-guardrails --skill typescript

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

4.7 KB, 986 tokens by cl100k_base, as published. Nobody here has run it

TypeScript Guardrails

These are hard rules. Check every piece of TypeScript you write, review, or modify against this list.


Types

  • DO NOT use enum. Use as const objects + inferred type instead.

    // wrong
    enum Status { Active, Inactive }
    
    // correct
    const STATUS = { Active: 'active', Inactive: 'inactive' } as const;
    type Status = typeof STATUS[keyof typeof STATUS];
    
  • DO NOT use any. Use unknown with type guards to narrow.

  • Prefer type over interface unless you need declaration merging, extends, or implements.

  • DO NOT use type assertions (as X) unless no alternative exists. Narrow with control flow instead. If unavoidable, add a comment explaining why.

    • Only exception: as Record<string, unknown> inside type guards, to access properties on a narrowed object. No other as casts — validate with typeof, in, or equality checks. When checking membership in a const object, widen the array type to ReadonlyArray<string> instead of casting the value:
      function isUser(value: unknown): value is User {
        if (typeof value !== 'object' || value === null) return false;
        const obj = value as Record<string, unknown>; // only acceptable assertion
        const validRoles: ReadonlyArray<string> = Object.values(USER_ROLE);
        return typeof obj.name === 'string' && typeof obj.role === 'string' && validRoles.includes(obj.role);
        // ↑ widen to ReadonlyArray<string> — do NOT cast obj.role as SomeType
      }
      
  • Use satisfies for type-safe object literals where you want inference + validation.

    const config = { port: 3000, host: 'localhost' } satisfies ServerConfig;
    
  • Explicit return types on all exported functions.


Imports / Exports

  • No barrel files (index.ts re-exports) except designated package entry points.

  • Explicit import pathsimport { bar } from './utils/bar', not from './utils'.

  • No default exports except config files (vite.config.ts, eslint.config.ts, etc.). Use named exports everywhere else.

  • ESM onlyimport/export. Never require() or module.exports.


Strict Mode

  • "strict": true in tsconfig — always. Do not loosen individual strict flags.

  • "noUncheckedIndexedAccess": true when the project supports it.

  • DO NOT use @ts-ignore. Use @ts-expect-error with an explanation comment if suppression is truly needed.

  • DO NOT use non-null assertions (!) unless provably safe. If used, add a comment explaining the proof.


Patterns

  • const by default. let only when reassignment is needed. Never var.

  • Exhaustive switches — always include a default case with a never check:

    default: {
      const _exhaustive: never = value;
      throw new Error(`Unhandled case: ${_exhaustive}`);
    }
    
  • Discriminated unions over type predicates when modeling variants.

  • Readonly by default — use readonly properties, ReadonlyArray<T>, Readonly<T>.

  • No classes unless required by a framework (e.g., Angular, NestJS). Prefer functions + closures.


Naming

ThingConventionExample
Fileskebab-caseuser-service.ts
Types / InterfacesPascalCaseUserProfile
Functions / variablescamelCasegetUserById
ConstantsUPPER_SNAKE_CASEMAX_RETRY_COUNT
Schema interfaces<Name>SchemaUserSchema

Error Handling

  • Never swallow errors — no empty catch blocks. Log, rethrow, or handle explicitly.

  • Typed errors — use custom error classes or discriminated union result types.

  • Avoid throw in library code when possible. Prefer a Result pattern or explicit error returns:

    type Result<T, E = Error> = { ok: true; value: T } | { ok: false; error: E };
    

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,512. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.