When to Use
User needs TypeScript expertise — from basic typing to advanced generics. Agent handles type narrowing, inference, discriminated unions, and strict mode patterns.
Quick Reference
| Topic | File |
|---|---|
| Generic patterns | generics.md |
| Utility types | utility-types.md |
| Declaration files | declarations.md |
| Migration from JS | migration.md |
Stop Using any
unknownforces you to narrow before use —anysilently breaks type safety- API responses: type them or use
unknown, neverany - When you don't know the type, that's
unknown, notany
Narrowing Failures
filter(Boolean)doesn't narrow — use.filter((x): x is T => Boolean(x))Object.keys(obj)returnsstring[], notkeyof typeof obj— intentional, objects can have extra keysArray.isArray()narrows toany[]— may need assertion for element typeinoperator narrows but only if property is in exactly one branch of union
Literal Type Traps
let x = "hello"isstring— useconstoras constfor literal type- Object properties widen:
{ status: "ok" }hasstatus: string— useas constor type annotation - Function return types widen — annotate explicitly for literal returns
Inference Limits
- Callbacks lose inference in some array methods — annotate parameter when TS guesses wrong
- Generic functions need usage to infer —
fn<T>()can't infer, pass a value or annotate - Nested generics often fail — break into steps with explicit types
Discriminated Unions
- Add a literal
typeorkindfield to each variant — enables exhaustive switch - Exhaustive check:
default: const _never: never = x— compile error if case missed - Don't mix discriminated with optional properties — breaks narrowing
satisfies vs Type Annotation
const x: Type = valwidens to Type — loses literal infoconst x = val satisfies Typekeeps literal, checks compatibility — prefer for config objects
Strict Null Handling
- Optional chaining
?.returnsundefined, notnull— matters for APIs expectingnull ??only catchesnull/undefined—||catches all falsy including0and""- Non-null
!should be last resort — prefer narrowing or early return
Module Boundaries
import typefor type-only imports — stripped at runtime, avoids bundler issues- Re-exporting types:
export type { X }— prevents accidental runtime dependency .d.tsaugmentation: usedeclare modulewith exact module path