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
npx -y skills add crustacean-dev/stack-guardrails --skill typescriptAssembled 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. Useas constobjects + 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. Useunknownwith type guards to narrow. -
Prefer
typeoverinterfaceunless you need declaration merging,extends, orimplements. -
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 otherascasts — validate withtypeof,in, or equality checks. When checking membership in a const object, widen the array type toReadonlyArray<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 }
- Only exception:
-
Use
satisfiesfor 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.tsre-exports) except designated package entry points. -
Explicit import paths —
import { bar } from './utils/bar', notfrom './utils'. -
No default exports except config files (
vite.config.ts,eslint.config.ts, etc.). Use named exports everywhere else. -
ESM only —
import/export. Neverrequire()ormodule.exports.
Strict Mode
-
"strict": truein tsconfig — always. Do not loosen individual strict flags. -
"noUncheckedIndexedAccess": truewhen the project supports it. -
DO NOT use
@ts-ignore. Use@ts-expect-errorwith 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
-
constby default.letonly when reassignment is needed. Nevervar. -
Exhaustive switches — always include a
defaultcase with anevercheck:default: { const _exhaustive: never = value; throw new Error(`Unhandled case: ${_exhaustive}`); } -
Discriminated unions over type predicates when modeling variants.
-
Readonly by default — use
readonlyproperties,ReadonlyArray<T>,Readonly<T>. -
No classes unless required by a framework (e.g., Angular, NestJS). Prefer functions + closures.
Naming
| Thing | Convention | Example |
|---|---|---|
| Files | kebab-case | user-service.ts |
| Types / Interfaces | PascalCase | UserProfile |
| Functions / variables | camelCase | getUserById |
| Constants | UPPER_SNAKE_CASE | MAX_RETRY_COUNT |
| Schema interfaces | <Name>Schema | UserSchema |
Error Handling
-
Never swallow errors — no empty
catchblocks. Log, rethrow, or handle explicitly. -
Typed errors — use custom error classes or discriminated union result types.
-
Avoid
throwin 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.