Back to skills
SKILL.md
Typescript Advanced
ASecurityUse 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
Works with
Security analysis
100/100npx -y skills add Harmitx7/tribunal-kit --skill typescript-advanced --agent claude-codeAre you the author of Typescript Advanced?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/harmitx7-typescript-advanced-tribunal-kit)---
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
Comments
Loading commentsβ¦