Skip to content
Back to skills

Typescript

ASecurity

This skill should be used when the user works with TypeScript files (.ts/.tsx), asks about "generics", "type guards", "utility types", "strict typing", "discriminated unions", or discusses type safety and inference. Provides patterns for Result types, exhaustive checks, branded types, and type-safe API contracts.

  • 19 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added September 3, 2026
developmenttypescriptgonodeapi

Works with

  • api

Security analysis

A100/100

Pro scans all 7 files and shows the line behind each finding

Scanned September 3, 2026

npx -y skills add dean0x/devflow --skill typescript --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Typescript?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Typescript
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dean0x-typescript/badge)](https://www.skillsdirectory.com/skills/dean0x-typescript)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: typescript
description: This skill should be used when the user works with TypeScript files (.ts/.tsx), asks about "generics", "type guards", "utility types", "strict typing", "discriminated unions", or discusses type safety and inference. Provides patterns for Result types, exhaustive checks, branded types, and type-safe API contracts.
user-invocable: false
allowed-tools: Read, Grep, Glob
activation:
  file-patterns:
    - "**/*.ts"
    - "**/*.tsx"
  exclude:
    - "node_modules/**"
    - "**/*.d.ts"
---

# TypeScript Patterns

## Iron Law

> **UNKNOWN OVER ANY**
>
> Never use `any`. Use `unknown` with type guards instead. `any` disables TypeScript's
> entire value proposition — if you need flexibility, use generics; if you need to handle
> arbitrary data, use `unknown` and validate. `any` is giving up. [1, Item 43]

## When This Skill Activates

- Working with TypeScript codebases or designing type-safe APIs
- Using generics, type guards, branded types, or conditional types

---

## Type Safety Fundamentals

### Prefer Unknown Over Any [1, Item 43]

Types are sets of values [1, Item 7]. `any` opts out entirely; `unknown` forces narrowing.

```typescript
// BAD: disables all type checking [4][17]
function parse(json: string): any { return JSON.parse(json); }
// GOOD: unknown forces narrowing before use [1, Item 43]
function parse(json: string): unknown { return JSON.parse(json); }
if (isUser(data)) console.log(data.name); // type-safe after guard
```

### Exhaustive Checks [1, Item 33][13]

```typescript
type Status = 'pending' | 'running' | 'completed' | 'failed';
function handleStatus(status: Status): string {
  switch (status) {
    case 'pending': return 'Waiting...';
    case 'running': return 'In progress...';
    case 'completed': return 'Done!';
    case 'failed': return 'Error occurred';
    default: const _: never = status; throw new Error(`Unhandled: ${_}`);
  }
}
```

---

## Generic Patterns [2][6]

```typescript
function first<T>(items: T[]): T | undefined { return items[0]; }
// Constrained key access [1, Item 54]
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; }
interface Repository<T, ID = string> { findById(id: ID): Promise<T | null>; save(entity: T): Promise<T>; }
```

---

## Discriminated Unions [1, Item 28][24]

Make illegal states unrepresentable — encode variants in the type [24].

```typescript
type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };
type RequestState<T> =
  | { status: 'idle' } | { status: 'loading' }
  | { status: 'success'; data: T } | { status: 'error'; error: Error };
```

---

## Branded Types [1, Item 37][22]

Structural typing treats `UserId` and `OrderId` (both `string`) as identical.
Brands add nominal distinction with zero runtime cost.

```typescript
declare const brand: unique symbol;
type Brand<T, B> = T & { [brand]: B };
type UserId  = Brand<string, 'UserId'>;
type OrderId = Brand<string, 'OrderId'>;

function getUser(id: UserId): User { ... }
// getUser(orderId) → Error: OrderId not assignable to UserId
```

---

## Conditional & Mapped Types [2][19]

```typescript
// Unwrap Promise return type via infer [19]
type AsyncReturnType<T extends (...args: any[]) => Promise<any>> =
  T extends (...args: any[]) => Promise<infer R> ? R : never;
// Pick by value type — key remapping with `as` [6][8]
type PickByType<T, V> = { [K in keyof T as T[K] extends V ? K : never]: T[K] };
// Recursive deep readonly [6]
type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P] };
```

---

## Anti-Patterns

| Bad | Good | Source |
|-----|------|--------|
| `data: any` | `data: unknown` + guard | [1, Item 43] |
| `data as User` | `if (isUser(data))` | [1, Item 9] |
| `user!.name!` | `user?.name ?? default` | [4] |
| `default: 'unknown'` | `const _: never = x` | [1, Item 33] |
| two IDs as `string` | branded types | [1, Item 37] |

---

## Extended References

- `references/sources.md` — Full bibliography [25 sources]
- `references/patterns.md` — Extended patterns with citations
- `references/violations.md` — Violation examples with citations
- `references/utility-types.md` — Utility types, branded types, template literals [6][15]
- `references/type-guards.md` — Advanced type guard patterns [2][6]
- `references/async.md` — Async TypeScript patterns [1, Item 25]

---

## Checklist

- [ ] No `any` types — `unknown` or generics [1, Item 43]
- [ ] Null/undefined handled explicitly [4]
- [ ] Discriminated unions for state variants [1, Item 28]
- [ ] Type guards narrow at runtime [2]
- [ ] Exhaustive switch with `never` [1, Item 33]
- [ ] Branded types for IDs and amounts [1, Item 37]
- [ ] Type-only imports (`import type`) [4]
- [ ] Strict tsconfig: `strict`, `noUncheckedIndexedAccess` [16]

Files in this skill

  • SKILL.md4.7 KB
  • references/async.md8.6 KB
  • references/patterns.md11.4 KB
  • references/sources.md4.5 KB
  • references/type-guards.md9.3 KB
  • references/utility-types.md7.8 KB
  • references/violations.md8 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.