# Type Safety

> Universal type safety principles — validate at boundaries, make invalid states unrepresentable, prefer explicit types over implicit. Applies to any typed language (TypeScript, Python type hints, Java, C#, Go). Load when writing or reviewing any code. Use when this capability is needed.

- Skill: `tomevault-io/type-safety-2` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/type-safety-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/type-safety-2/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/type-safety-2

---


Always-on type safety principles:

**Validate at the boundary, trust inside**
- Data from external sources (API requests, file input, user input, environment variables) must be validated at the entry point before it enters the system
- Once validated, pass typed values — never re-validate the same data deep inside the system
- A function that accepts typed parameters should be able to trust those types

**Make invalid states unrepresentable**
- Model state with variants, not boolean flags — parallel flags create impossible combinations
- A loading state should not also carry data; a success state should not also carry an error
- If two values are always changed together, model them as a single value

**Prefer explicit over implicit**
- Explicit type annotations on all public/exported functions
- Infer private/internal types from implementation only when the type is obvious
- Never use a "catch-all" type (`any`, `object`, untyped `dict`) without a comment explaining why

**Fail safely at the boundary, never silently inside**
- When validation fails at the boundary, fail loudly (throw, return error) — never proceed with invalid data
- Avoid silent coercions (e.g. `"42" → 42`, `null → 0`) — they hide bugs
- Prefer returning explicit error values over null/undefined for expected failure cases

**Make the language's type checker work for you**
- Exhaustive checks: when you handle variants, ensure the language catches unhandled new cases at compile time
- Branded/nominal types for domain IDs: a `UserId` and a `PostId` should not be interchangeable even if both are strings
- Favour composition of small, precise types over large generic ones

**For language-specific implementation, consult your language layer:**
- TypeScript → `layers/language/typescript/`
- Python → `layers/language/python/` *(stub)*
- Java / Kotlin → `layers/language/java/` *(stub)*

---
> Source: [manikumarkv/devrunway-claude-plugin](https://github.com/manikumarkv/devrunway-claude-plugin) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-05-22 -->

