Skip to content
Back to skills

Typescript Advanced

ASecurity

Use when Advanced TypeScript mastery. Generics with constraints, conditional types, mapped types, template literal types, the satisfies operator, discriminated unions, branded/nominal types, type-level programming, utility type internals, variance annotations, module augmentation, and declaration merging. Use when writing complex type definitions, building type-safe libraries, or solving \"how do I type this?\" problems.

  • 5 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 27, 2026
ai-agentstypescriptgobashexpressapiperformance

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 27, 2026

npx -y skills add Harmitx7/tribunal-kit --skill typescript-advanced --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Typescript Advanced?

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

Security grade badge for Typescript Advanced
[![Security: A β€” Skills Directory](https://www.skillsdirectory.com/api/skills/harmitx7-typescript-advanced-tribunal-kit/badge)](https://www.skillsdirectory.com/skills/harmitx7-typescript-advanced-tribunal-kit)

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-advanced
description: "Use when Advanced TypeScript mastery. Generics with constraints, conditional types, mapped types, template literal types, the satisfies operator, discriminated unions, branded/nominal types, type-level programming, utility type internals, variance annotations, module augmentation, and declaration merging. Use when writing complex type definitions, building type-safe libraries, or solving \"how do I type this?\" problems."
version: 5.0.0
last-updated: 2026-09-13
skills:
  - clean-code
  - data-validation-schemas
  - lint-and-validate
tools: Read, Grep, Glob, Bash, Edit, Write
scripts-binding:
  - .agent/scripts/lint_runner.js
  - .agent/scripts/verify_all.js
---

# Advanced TypeScript β€” Type-Level Mastery

---

## πŸ› οΈ Technical Architecture & Reference Recipes

---

## 2026 TypeScript Performance & Compiler Invariants

1. **Explicit Return Types on Exports (`isolatedDeclarations`)**: Always add explicit return types to exported functions/methods for fast, parallel build compilation.
2. **Interface Extension Over Deep Intersections**: Use `interface B extends A` instead of `type B = A & { ... }`. Interfaces are cached by TS compiler's internal type-checker, preventing quadratic build slowdowns.
3. **Safe Indexed Access**: Handle `undefined` when reading objects/arrays under `noUncheckedIndexedAccess`.
4. **Const Type Parameters**: Use `function parse<const T>(val: T)` to preserve literal types without requiring the caller to write `as const`.

## Hallucination Traps (Read First)

- ❌ Using `as any` to silence type errors -> βœ… Fix the type or use `unknown` + type guard; `as any` masks runtime errors
- ❌ Using deep recursive conditional types that trigger `Type instantiation is excessively deep` -> βœ… Use iteration or flat lookup tables
- ❌ Overusing `type X = A & B & C & D` -> βœ… Use `interface` extension to preserve compiler performance
- ❌ Manual `x is T` when TS 5.5+ infers the predicate -> βœ… Write natural predicate functions without unnecessary type assertion casts

---

## Generics with Constraints

```typescript
// βœ… Constrained generics β€” T must have an id
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
  return items.find(item => item.id === id);
}

// βœ… Multiple constraints
function merge<T extends object, U extends object>(a: T, b: U): T & U {
  return { ...a, ...b };
}

// βœ… keyof constraint β€” K must be a key of T
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Alice', age: 30 };
const name = getProperty(user, 'name'); // type: string
const age = getProperty(user, 'age'); // type: number
// getProperty(user, "email");           // ❌ Compile error β€” "email" not in keyof

// βœ… Default generic parameters
function createState<T = string>(initial: T): { value: T; set: (v: T) => void } {
  let value = initial;
  return {
    value,
    set: v => {
      value = v;
    },
  };
}
```

---

## Discriminated Unions (The Most Useful Pattern)

```typescript
// βœ… Tagged unions β€” TypeScript narrows automatically
type Result<T, E = Error> =
  | { success: true; data: T }
  | { success: false; error: E };

function divide(a: number, b: number): Result<number, string> {
  if (b === 0) return { success: false, error: "Division by zero" };
  return { success: true, data: a / b };
}

const result = divide(10, 3);
if (result.success) {
  console.log(result.data);   // TypeScript KNOWS data exists
} else {
  console.log(result.error);  // TypeScript KNOWS error exists
}

// βœ… State machines with discriminated unions
type RequestState<T> =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; error: Error };

function renderUser(state: RequestState<User>) {
  switch (state.status) {
    case "idle":    return <p>Click to load</p>;
    case "loading": return <Spinner />;
    case "success": return <UserCard user={state.data} />;
    case "error":   return <ErrorBanner error={state.error} />;
  }
}
// βœ… TypeScript ensures ALL cases are handled (exhaustive checking)
```

---

## Conditional Types

```typescript
// βœ… Type-level if/else
type IsString<T> = T extends string ? true : false;

type A = IsString<'hello'>; // true
type B = IsString<42>; // false

// βœ… Extract return type of async functions
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

type UserData = UnwrapPromise<Promise<{ name: string }>>;
// β†’ { name: string }

// βœ… Practical: API response type extraction
type ApiResponse<T> = T extends (...args: any[]) => Promise<infer R> ? R : never;

declare function getUsers(): Promise<User[]>;
type Users = ApiResponse<typeof getUsers>; // User[]

// βœ… Distributive conditional types
type NonNullable<T> = T extends null | undefined ? never : T;

type Clean = NonNullable<string | null | undefined>; // string
```

---

## Mapped Types

```typescript
// βœ… Transform every property of a type
type Readonly<T> = { readonly [K in keyof T]: T[K] };
type Partial<T> = { [K in keyof T]?: T[K] };
type Required<T> = { [K in keyof T]-?: T[K] };

// βœ… Practical: Create a "form touched" state
type TouchedFields<T> = { [K in keyof T]: boolean };

interface LoginForm {
  email: string;
  password: string;
}

type LoginTouched = TouchedFields<LoginForm>;
// β†’ { email: boolean; password: boolean }

// βœ… Key remapping with `as`
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<{ name: string; age: number }>;
// β†’ { getName: () => string; getAge: () => number }

// βœ… Filter keys by value type
type StringKeys<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K];
};

type OnlyStrings = StringKeys<{ name: string; age: number; email: string }>;
// β†’ { name: string; email: string }
```

---

## Template Literal Types

```typescript
// βœ… Type-safe string patterns
type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';
type APIRoute = `/api/${string}`;
type EventName = `on${Capitalize<string>}`;

// βœ… Practical: CSS unit types
type CSSUnit = 'px' | 'rem' | 'em' | 'vh' | 'vw' | '%';
type CSSValue = `${number}${CSSUnit}`;

const width: CSSValue = '100px'; // βœ…
// const bad: CSSValue = "100";     // ❌ Compile error

// βœ… Route parameter extraction
type ExtractParams<T extends string> = T extends `${string}:${infer Param}/${infer Rest}`
  ? Param | ExtractParams<Rest>
  : T extends `${string}:${infer Param}`
    ? Param
    : never;

type UserRouteParams = ExtractParams<'/users/:userId/posts/:postId'>;
// β†’ "userId" | "postId"
```

---

## The `satisfies` Operator (TS 5.0+)

```typescript
// βœ… satisfies checks the type WITHOUT widening it
type ColorMap = Record<string, [number, number, number] | string>;

// With `as` β€” loses specificity
const colorsAs = {
  red: [255, 0, 0],
  green: '#00ff00',
} as ColorMap;
colorsAs.red.map(x => x); // ❌ Error: string | number[] has no .map

// With `satisfies` β€” keeps literal types
const colors = {
  red: [255, 0, 0],
  green: '#00ff00',
} satisfies ColorMap;
colors.red.map(x => x); // βœ… TypeScript knows it's a tuple
colors.green.toUpperCase(); // βœ… TypeScript knows it's a string
```

---

## Branded / Nominal Types

```typescript
// βœ… Prevent accidental mixing of same-shaped types
type UserId = string & { readonly __brand: "UserId" };
type OrderId = string & { readonly __brand: "OrderId" };

function createUserId(id: string): UserId { return id as UserId; }
function createOrderId(id: string): OrderId { return id as OrderId; }

function getUser(id: UserId): Promise<User> { ... }

const userId = createUserId("user_123");
const orderId = createOrderId("order_456");

getUser(userId);   // βœ… Correct
// getUser(orderId);  // ❌ Compile error β€” OrderId is not UserId

// βœ… Branded number types
type Cents = number & { readonly __brand: "Cents" };
type Dollars = number & { readonly __brand: "Dollars" };

function centsToDollars(cents: Cents): Dollars {
  return (cents / 100) as Dollars;
}
```

---

## Utility Types (Know the Built-ins)

```typescript
// Don't reimplement what TypeScript provides

Pick<T, K>; // Select specific keys
Omit<T, K>; // Remove specific keys
Partial<T>; // All properties optional
Required<T>; // All properties required
Readonly<T>; // All properties readonly
Record<K, V>; // Object with keys K and values V
Extract<T, U>; // Members of T assignable to U
Exclude<T, U>; // Members of T NOT assignable to U
NonNullable<T>; // Remove null and undefined
ReturnType<T>; // Return type of a function
Parameters<T>; // Parameter types of a function as tuple
Awaited<T>; // Unwrap Promise<T> recursively
```

---

## Anti-Patterns

```
❌ `as any` β€” hides runtime crashes. Fix the type or use `as unknown as T` with a comment.
❌ `// @ts-ignore` β€” use `// @ts-expect-error` with a reason comment instead.
❌ `interface` for unions β€” interfaces can't express `A | B`. Use `type`.
❌ Overusing generics β€” if <T> is only used once, you probably don't need it.
❌ `enum` for new code β€” use `as const` objects or union types instead.
❌ Type assertions in tests β€” use proper type guards or schema validation.
❌ `!` (non-null assertion) β€” it's a lie. Use optional chaining or narrowing.
```

```typescript
// ❌ BAD: Non-null assertion
const element = document.getElementById('app')!;

// βœ… GOOD: Narrowing
const element = document.getElementById('app');
if (!element) throw new Error('Missing #app element');
// element is now guaranteed non-null
```

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…