mcpbeat Sign in

Typescript Best Practices Skill for Claude

TypeScript best practices. Use when reading or editing any .ts or .tsx file.

3k tokens
context cost
the whole folder, loaded on every use
2
files
instructions only
0
copies elsewhere
how many repositories repackaged it
255
stars on the repo
on the repository, not the skill itself

Install

one command, takes just this skill from the repository
npx skills add https://github.com/michael-denyer/pstack-claude --skill typescript-best-practices

What comes with it

8 860 bytes besides the instruction
references/patterns.md

The instruction itself

1 sections, as written by the author

TypeScript best practices

Apply the type-system-discipline principle skill first.

| Rule | Summary |

|------|---------|

| Discriminated unions | Model variants with a kind literal discriminant so impossible states can't be represented. No optional-field bags. |

| Branded types | Brand primitives with & { readonly __brand: "X" } so they can't be mixed up. Validate once at the boundary. |

| Constructive modeling | Build the shape so the illegal value can't be constructed. [T, ...T[]] for non-empty, [T, T][] for even length, start plus duration for a range. Not a runtime guard, not a wish for refinement types. |

| Simplest total type | Keep T[] while every operation on it stays total. Strengthen to NonEmpty<T> only where the loose type forces !, a cast, or a "should never happen" throw. |

| unknown over any | External data is unknown. |

| Schemas before guards | Before hand-writing a property-by-property type guard, use the repository's runtime schema library and infer the type from the schema, such as z.infer. |

| No as casts | Every as is a runtime crash waiting. Cast only after validation. |

| Narrowing hierarchy | Discriminant switch > in operator > typeof/instanceof > user-defined type guard > as. |

| Type guards | Must verify the claim. A lying guard is worse than as because the bug hides behind a name that says it's safe. Name them isX or hasX. |

| Exhaustiveness | Inline const _exhaustive: never = x; in default arms so the compiler errors when a new variant is added. |

| satisfies over as | Validates the value without widening literal types. |

| Boundary validation | Parse where data crosses in, into a named domain type. Record<string, unknown> (however spelled) stops at that parse. Trust types inside. See the boundary-discipline principle skill. |

| Schema-derived types | Reach for Pick/Omit/Parameters/ReturnType/Awaited/typeof before declaring a new interface. |

| Object args | Pass objects, not positional, so argument order is self-documenting. Skip on hot paths (per-frame render, tokenizers, parsers). |

| Real tests | Don't mock what you can run. Prefer the framework's real test primitives with leak/disposable checks, and verify UI in a running build. Mock only what you can't run locally. |

| Structured telemetry | Prefer structured logger diagnostics with enough context to debug from an id. No console.log in shipped code. |

Examples: references/patterns.md.

How to use it

Copy the folder

Take michael-denyer/typescript-best-practices from the repository into ~/.claude/skills for personal use, or into .claude/skills inside a project.

Check the name does not clash

The agent identifies a skill by the name field in its header. Two skills with the same name cannot sit side by side — one of them will be ignored.