tribunal-kit 4.3.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/scripts/case_law_manager.js +684 -684
- package/.agent/scripts/graph_builder.js +199 -0
- package/.agent/scripts/graph_zoom.js +154 -0
- package/.agent/skills/agent-organizer/SKILL.md +9 -1
- package/.agent/skills/agentic-patterns/SKILL.md +9 -1
- package/.agent/skills/ai-prompt-injection-defense/SKILL.md +9 -1
- package/.agent/skills/api-patterns/SKILL.md +206 -198
- package/.agent/skills/api-security-auditor/SKILL.md +9 -1
- package/.agent/skills/app-builder/SKILL.md +9 -1
- package/.agent/skills/app-builder/templates/SKILL.md +77 -69
- package/.agent/skills/appflow-wireframe/SKILL.md +9 -1
- package/.agent/skills/architecture/SKILL.md +9 -1
- package/.agent/skills/authentication-best-practices/SKILL.md +9 -1
- package/.agent/skills/bash-linux/SKILL.md +9 -1
- package/.agent/skills/behavioral-modes/SKILL.md +9 -1
- package/.agent/skills/brainstorming/SKILL.md +9 -1
- package/.agent/skills/building-native-ui/SKILL.md +9 -1
- package/.agent/skills/clean-code/SKILL.md +9 -1
- package/.agent/skills/code-review-checklist/SKILL.md +9 -1
- package/.agent/skills/config-validator/SKILL.md +9 -1
- package/.agent/skills/csharp-developer/SKILL.md +9 -1
- package/.agent/skills/data-validation-schemas/SKILL.md +287 -279
- package/.agent/skills/database-design/SKILL.md +199 -191
- package/.agent/skills/deployment-procedures/SKILL.md +9 -1
- package/.agent/skills/devops-engineer/SKILL.md +9 -1
- package/.agent/skills/devops-incident-responder/SKILL.md +9 -1
- package/.agent/skills/documentation-templates/SKILL.md +9 -1
- package/.agent/skills/edge-computing/SKILL.md +9 -1
- package/.agent/skills/error-resilience/SKILL.md +387 -379
- package/.agent/skills/extract-design-system/SKILL.md +9 -1
- package/.agent/skills/framer-motion-expert/SKILL.md +203 -195
- package/.agent/skills/frontend-design/SKILL.md +160 -152
- package/.agent/skills/game-design-expert/SKILL.md +9 -1
- package/.agent/skills/game-engineering-expert/SKILL.md +9 -1
- package/.agent/skills/geo-fundamentals/SKILL.md +9 -1
- package/.agent/skills/github-operations/SKILL.md +9 -1
- package/.agent/skills/gsap-core/SKILL.md +54 -46
- package/.agent/skills/gsap-frameworks/SKILL.md +54 -46
- package/.agent/skills/gsap-performance/SKILL.md +54 -46
- package/.agent/skills/gsap-plugins/SKILL.md +54 -46
- package/.agent/skills/gsap-react/SKILL.md +54 -46
- package/.agent/skills/gsap-scrolltrigger/SKILL.md +54 -46
- package/.agent/skills/gsap-timeline/SKILL.md +54 -46
- package/.agent/skills/gsap-utils/SKILL.md +54 -46
- package/.agent/skills/i18n-localization/SKILL.md +9 -1
- package/.agent/skills/intelligent-routing/SKILL.md +38 -30
- package/.agent/skills/knowledge-graph/SKILL.md +36 -0
- package/.agent/skills/lint-and-validate/SKILL.md +9 -1
- package/.agent/skills/llm-engineering/SKILL.md +9 -1
- package/.agent/skills/local-first/SKILL.md +9 -1
- package/.agent/skills/mcp-builder/SKILL.md +9 -1
- package/.agent/skills/mobile-design/SKILL.md +222 -214
- package/.agent/skills/monorepo-management/SKILL.md +293 -285
- package/.agent/skills/motion-engineering/SKILL.md +193 -185
- package/.agent/skills/nextjs-react-expert/SKILL.md +193 -185
- package/.agent/skills/nodejs-best-practices/SKILL.md +9 -1
- package/.agent/skills/observability/SKILL.md +9 -1
- package/.agent/skills/parallel-agents/SKILL.md +9 -1
- package/.agent/skills/performance-profiling/SKILL.md +9 -1
- package/.agent/skills/plan-writing/SKILL.md +9 -1
- package/.agent/skills/platform-engineer/SKILL.md +9 -1
- package/.agent/skills/playwright-best-practices/SKILL.md +9 -1
- package/.agent/skills/powershell-windows/SKILL.md +9 -1
- package/.agent/skills/project-idioms/SKILL.md +9 -1
- package/.agent/skills/python-patterns/SKILL.md +9 -1
- package/.agent/skills/python-pro/SKILL.md +282 -274
- package/.agent/skills/react-specialist/SKILL.md +236 -228
- package/.agent/skills/readme-builder/SKILL.md +9 -1
- package/.agent/skills/realtime-patterns/SKILL.md +9 -1
- package/.agent/skills/red-team-tactics/SKILL.md +9 -1
- package/.agent/skills/rust-pro/SKILL.md +9 -1
- package/.agent/skills/seo-fundamentals/SKILL.md +9 -1
- package/.agent/skills/server-management/SKILL.md +9 -1
- package/.agent/skills/shadcn-ui-expert/SKILL.md +9 -1
- package/.agent/skills/skill-creator/SKILL.md +9 -1
- package/.agent/skills/sql-pro/SKILL.md +9 -1
- package/.agent/skills/supabase-postgres-best-practices/SKILL.md +9 -1
- package/.agent/skills/swiftui-expert/SKILL.md +9 -1
- package/.agent/skills/systematic-debugging/SKILL.md +9 -1
- package/.agent/skills/tailwind-patterns/SKILL.md +9 -1
- package/.agent/skills/tdd-workflow/SKILL.md +9 -1
- package/.agent/skills/test-result-analyzer/SKILL.md +9 -1
- package/.agent/skills/testing-patterns/SKILL.md +9 -1
- package/.agent/skills/trend-researcher/SKILL.md +9 -1
- package/.agent/skills/typescript-advanced/SKILL.md +294 -286
- package/.agent/skills/ui-ux-pro-max/SKILL.md +9 -1
- package/.agent/skills/ui-ux-researcher/SKILL.md +9 -1
- package/.agent/skills/vue-expert/SKILL.md +234 -226
- package/.agent/skills/vulnerability-scanner/SKILL.md +9 -1
- package/.agent/skills/web-accessibility-auditor/SKILL.md +9 -1
- package/.agent/skills/web-design-guidelines/SKILL.md +9 -1
- package/.agent/skills/webapp-testing/SKILL.md +9 -1
- package/.agent/skills/whimsy-injector/SKILL.md +9 -1
- package/.agent/skills/workflow-optimizer/SKILL.md +9 -1
- package/README.md +242 -242
- package/bin/tribunal-kit.js +30 -22
- package/package.json +81 -80
- package/scripts/validate-payload.js +73 -0
|
@@ -555,4 +555,12 @@ Review these questions before confirming output:
|
|
|
555
555
|
|
|
556
556
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
557
557
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
558
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
558
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
## Pre-Flight Checklist
|
|
562
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
563
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
564
|
+
|
|
565
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
566
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -150,4 +150,12 @@ Review these questions before confirming output:
|
|
|
150
150
|
|
|
151
151
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
152
152
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
153
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
153
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
## Pre-Flight Checklist
|
|
157
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
158
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
159
|
+
|
|
160
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
161
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -298,4 +298,12 @@ Review these questions before confirming output:
|
|
|
298
298
|
|
|
299
299
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
300
300
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
301
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
301
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
## Pre-Flight Checklist
|
|
305
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
306
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
307
|
+
|
|
308
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
309
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -551,4 +551,12 @@ Review these questions before confirming output:
|
|
|
551
551
|
|
|
552
552
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
553
553
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
554
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
554
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
## Pre-Flight Checklist
|
|
558
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
559
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
560
|
+
|
|
561
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
562
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -226,4 +226,12 @@ Review these questions before confirming output:
|
|
|
226
226
|
|
|
227
227
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
228
228
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
229
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
229
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
## Pre-Flight Checklist
|
|
233
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
234
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
235
|
+
|
|
236
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
237
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|
|
@@ -1,288 +1,288 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: typescript-advanced
|
|
3
|
-
description: 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.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
-
version: 1.0.0
|
|
6
|
-
last-updated: 2026-04-17
|
|
7
|
-
applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Hallucination Traps (Read First)
|
|
11
|
-
- ❌ Using `as any` to silence type errors -> ✅ Fix the type; `as any` hides bugs that crash at runtime
|
|
12
|
-
- ❌ Using `interface` when `type` is needed (unions, mapped types) -> ✅ `type` for unions/intersections/mapped; `interface` for objects that may be extended
|
|
13
|
-
- ❌ Overcomplicating types — if a type takes 30 seconds to read, simplify it -> ✅ Types serve the developer, not the other way around
|
|
14
|
-
|
|
15
|
-
---
|
|
16
|
-
|
|
17
|
-
# Advanced TypeScript — Type-Level Mastery
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Generics with Constraints
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
// ✅ Constrained generics — T must have an id
|
|
25
|
-
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
|
|
26
|
-
return items.find((item) => item.id === id);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ✅ Multiple constraints
|
|
30
|
-
function merge<T extends object, U extends object>(a: T, b: U): T & U {
|
|
31
|
-
return { ...a, ...b };
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ✅ keyof constraint — K must be a key of T
|
|
35
|
-
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
|
|
36
|
-
return obj[key];
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const user = { name: "Alice", age: 30 };
|
|
40
|
-
const name = getProperty(user, "name"); // type: string
|
|
41
|
-
const age = getProperty(user, "age"); // type: number
|
|
42
|
-
// getProperty(user, "email"); // ❌ Compile error — "email" not in keyof
|
|
43
|
-
|
|
44
|
-
// ✅ Default generic parameters
|
|
45
|
-
function createState<T = string>(initial: T): { value: T; set: (v: T) => void } {
|
|
46
|
-
let value = initial;
|
|
47
|
-
return { value, set: (v) => { value = v; } };
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Discriminated Unions (The Most Useful Pattern)
|
|
54
|
-
|
|
55
|
-
```typescript
|
|
56
|
-
// ✅ Tagged unions — TypeScript narrows automatically
|
|
57
|
-
type Result<T, E = Error> =
|
|
58
|
-
| { success: true; data: T }
|
|
59
|
-
| { success: false; error: E };
|
|
60
|
-
|
|
61
|
-
function divide(a: number, b: number): Result<number, string> {
|
|
62
|
-
if (b === 0) return { success: false, error: "Division by zero" };
|
|
63
|
-
return { success: true, data: a / b };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const result = divide(10, 3);
|
|
67
|
-
if (result.success) {
|
|
68
|
-
console.log(result.data); // TypeScript KNOWS data exists
|
|
69
|
-
} else {
|
|
70
|
-
console.log(result.error); // TypeScript KNOWS error exists
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// ✅ State machines with discriminated unions
|
|
74
|
-
type RequestState<T> =
|
|
75
|
-
| { status: "idle" }
|
|
76
|
-
| { status: "loading" }
|
|
77
|
-
| { status: "success"; data: T }
|
|
78
|
-
| { status: "error"; error: Error };
|
|
79
|
-
|
|
80
|
-
function renderUser(state: RequestState<User>) {
|
|
81
|
-
switch (state.status) {
|
|
82
|
-
case "idle": return <p>Click to load</p>;
|
|
83
|
-
case "loading": return <Spinner />;
|
|
84
|
-
case "success": return <UserCard user={state.data} />;
|
|
85
|
-
case "error": return <ErrorBanner error={state.error} />;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
// ✅ TypeScript ensures ALL cases are handled (exhaustive checking)
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Conditional Types
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
// ✅ Type-level if/else
|
|
97
|
-
type IsString<T> = T extends string ? true : false;
|
|
98
|
-
|
|
99
|
-
type A = IsString<"hello">; // true
|
|
100
|
-
type B = IsString<42>; // false
|
|
101
|
-
|
|
102
|
-
// ✅ Extract return type of async functions
|
|
103
|
-
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
|
|
104
|
-
|
|
105
|
-
type UserData = UnwrapPromise<Promise<{ name: string }>>;
|
|
106
|
-
// → { name: string }
|
|
107
|
-
|
|
108
|
-
// ✅ Practical: API response type extraction
|
|
109
|
-
type ApiResponse<T> = T extends (...args: any[]) => Promise<infer R> ? R : never;
|
|
110
|
-
|
|
111
|
-
declare function getUsers(): Promise<User[]>;
|
|
112
|
-
type Users = ApiResponse<typeof getUsers>; // User[]
|
|
113
|
-
|
|
114
|
-
// ✅ Distributive conditional types
|
|
115
|
-
type NonNullable<T> = T extends null | undefined ? never : T;
|
|
116
|
-
|
|
117
|
-
type Clean = NonNullable<string | null | undefined>; // string
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Mapped Types
|
|
123
|
-
|
|
124
|
-
```typescript
|
|
125
|
-
// ✅ Transform every property of a type
|
|
126
|
-
type Readonly<T> = { readonly [K in keyof T]: T[K] };
|
|
127
|
-
type Partial<T> = { [K in keyof T]?: T[K] };
|
|
128
|
-
type Required<T> = { [K in keyof T]-?: T[K] };
|
|
129
|
-
|
|
130
|
-
// ✅ Practical: Create a "form touched" state
|
|
131
|
-
type TouchedFields<T> = { [K in keyof T]: boolean };
|
|
132
|
-
|
|
133
|
-
interface LoginForm {
|
|
134
|
-
email: string;
|
|
135
|
-
password: string;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
type LoginTouched = TouchedFields<LoginForm>;
|
|
139
|
-
// → { email: boolean; password: boolean }
|
|
140
|
-
|
|
141
|
-
// ✅ Key remapping with `as`
|
|
142
|
-
type Getters<T> = {
|
|
143
|
-
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
type UserGetters = Getters<{ name: string; age: number }>;
|
|
147
|
-
// → { getName: () => string; getAge: () => number }
|
|
148
|
-
|
|
149
|
-
// ✅ Filter keys by value type
|
|
150
|
-
type StringKeys<T> = {
|
|
151
|
-
[K in keyof T as T[K] extends string ? K : never]: T[K];
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
type OnlyStrings = StringKeys<{ name: string; age: number; email: string }>;
|
|
155
|
-
// → { name: string; email: string }
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## Template Literal Types
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
// ✅ Type-safe string patterns
|
|
164
|
-
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
165
|
-
type APIRoute = `/api/${string}`;
|
|
166
|
-
type EventName = `on${Capitalize<string>}`;
|
|
167
|
-
|
|
168
|
-
// ✅ Practical: CSS unit types
|
|
169
|
-
type CSSUnit = "px" | "rem" | "em" | "vh" | "vw" | "%";
|
|
170
|
-
type CSSValue = `${number}${CSSUnit}`;
|
|
171
|
-
|
|
172
|
-
const width: CSSValue = "100px"; // ✅
|
|
173
|
-
// const bad: CSSValue = "100"; // ❌ Compile error
|
|
174
|
-
|
|
175
|
-
// ✅ Route parameter extraction
|
|
176
|
-
type ExtractParams<T extends string> =
|
|
177
|
-
T extends `${string}:${infer Param}/${infer Rest}`
|
|
178
|
-
? Param | ExtractParams<Rest>
|
|
179
|
-
: T extends `${string}:${infer Param}`
|
|
180
|
-
? Param
|
|
181
|
-
: never;
|
|
182
|
-
|
|
183
|
-
type UserRouteParams = ExtractParams<"/users/:userId/posts/:postId">;
|
|
184
|
-
// → "userId" | "postId"
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
---
|
|
188
|
-
|
|
189
|
-
## The `satisfies` Operator (TS 5.0+)
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
// ✅ satisfies checks the type WITHOUT widening it
|
|
193
|
-
type ColorMap = Record<string, [number, number, number] | string>;
|
|
194
|
-
|
|
195
|
-
// With `as` — loses specificity
|
|
196
|
-
const colorsAs = {
|
|
197
|
-
red: [255, 0, 0],
|
|
198
|
-
green: "#00ff00",
|
|
199
|
-
} as ColorMap;
|
|
200
|
-
colorsAs.red.map(x => x); // ❌ Error: string | number[] has no .map
|
|
201
|
-
|
|
202
|
-
// With `satisfies` — keeps literal types
|
|
203
|
-
const colors = {
|
|
204
|
-
red: [255, 0, 0],
|
|
205
|
-
green: "#00ff00",
|
|
206
|
-
} satisfies ColorMap;
|
|
207
|
-
colors.red.map(x => x); // ✅ TypeScript knows it's a tuple
|
|
208
|
-
colors.green.toUpperCase(); // ✅ TypeScript knows it's a string
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
---
|
|
212
|
-
|
|
213
|
-
## Branded / Nominal Types
|
|
214
|
-
|
|
215
|
-
```typescript
|
|
216
|
-
// ✅ Prevent accidental mixing of same-shaped types
|
|
217
|
-
type UserId = string & { readonly __brand: "UserId" };
|
|
218
|
-
type OrderId = string & { readonly __brand: "OrderId" };
|
|
219
|
-
|
|
220
|
-
function createUserId(id: string): UserId { return id as UserId; }
|
|
221
|
-
function createOrderId(id: string): OrderId { return id as OrderId; }
|
|
222
|
-
|
|
223
|
-
function getUser(id: UserId): Promise<User> { ... }
|
|
224
|
-
|
|
225
|
-
const userId = createUserId("user_123");
|
|
226
|
-
const orderId = createOrderId("order_456");
|
|
227
|
-
|
|
228
|
-
getUser(userId); // ✅ Correct
|
|
229
|
-
// getUser(orderId); // ❌ Compile error — OrderId is not UserId
|
|
230
|
-
|
|
231
|
-
// ✅ Branded number types
|
|
232
|
-
type Cents = number & { readonly __brand: "Cents" };
|
|
233
|
-
type Dollars = number & { readonly __brand: "Dollars" };
|
|
234
|
-
|
|
235
|
-
function centsToDollars(cents: Cents): Dollars {
|
|
236
|
-
return (cents / 100) as Dollars;
|
|
237
|
-
}
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
---
|
|
241
|
-
|
|
242
|
-
## Utility Types (Know the Built-ins)
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
// Don't reimplement what TypeScript provides
|
|
246
|
-
|
|
247
|
-
Pick<T, K> // Select specific keys
|
|
248
|
-
Omit<T, K> // Remove specific keys
|
|
249
|
-
Partial<T> // All properties optional
|
|
250
|
-
Required<T> // All properties required
|
|
251
|
-
Readonly<T> // All properties readonly
|
|
252
|
-
Record<K, V> // Object with keys K and values V
|
|
253
|
-
Extract<T, U> // Members of T assignable to U
|
|
254
|
-
Exclude<T, U> // Members of T NOT assignable to U
|
|
255
|
-
NonNullable<T> // Remove null and undefined
|
|
256
|
-
ReturnType<T> // Return type of a function
|
|
257
|
-
Parameters<T> // Parameter types of a function as tuple
|
|
258
|
-
Awaited<T> // Unwrap Promise<T> recursively
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
---
|
|
262
|
-
|
|
263
|
-
## Anti-Patterns
|
|
264
|
-
|
|
265
|
-
```
|
|
266
|
-
❌ `as any` — hides runtime crashes. Fix the type or use `as unknown as T` with a comment.
|
|
267
|
-
❌ `// @ts-ignore` — use `// @ts-expect-error` with a reason comment instead.
|
|
268
|
-
❌ `interface` for unions — interfaces can't express `A | B`. Use `type`.
|
|
269
|
-
❌ Overusing generics — if <T> is only used once, you probably don't need it.
|
|
270
|
-
❌ `enum` for new code — use `as const` objects or union types instead.
|
|
271
|
-
❌ Type assertions in tests — use proper type guards or schema validation.
|
|
272
|
-
❌ `!` (non-null assertion) — it's a lie. Use optional chaining or narrowing.
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
```typescript
|
|
276
|
-
// ❌ BAD: Non-null assertion
|
|
277
|
-
const element = document.getElementById("app")!;
|
|
278
|
-
|
|
279
|
-
// ✅ GOOD: Narrowing
|
|
280
|
-
const element = document.getElementById("app");
|
|
281
|
-
if (!element) throw new Error("Missing #app element");
|
|
282
|
-
// element is now guaranteed non-null
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
---
|
|
1
|
+
---
|
|
2
|
+
name: typescript-advanced
|
|
3
|
+
description: 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.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
last-updated: 2026-04-17
|
|
7
|
+
applies-to-model: gemini-2.5-pro, claude-3-7-sonnet
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Hallucination Traps (Read First)
|
|
11
|
+
- ❌ Using `as any` to silence type errors -> ✅ Fix the type; `as any` hides bugs that crash at runtime
|
|
12
|
+
- ❌ Using `interface` when `type` is needed (unions, mapped types) -> ✅ `type` for unions/intersections/mapped; `interface` for objects that may be extended
|
|
13
|
+
- ❌ Overcomplicating types — if a type takes 30 seconds to read, simplify it -> ✅ Types serve the developer, not the other way around
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# Advanced TypeScript — Type-Level Mastery
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Generics with Constraints
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
// ✅ Constrained generics — T must have an id
|
|
25
|
+
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
|
|
26
|
+
return items.find((item) => item.id === id);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ✅ Multiple constraints
|
|
30
|
+
function merge<T extends object, U extends object>(a: T, b: U): T & U {
|
|
31
|
+
return { ...a, ...b };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// ✅ keyof constraint — K must be a key of T
|
|
35
|
+
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
|
|
36
|
+
return obj[key];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const user = { name: "Alice", age: 30 };
|
|
40
|
+
const name = getProperty(user, "name"); // type: string
|
|
41
|
+
const age = getProperty(user, "age"); // type: number
|
|
42
|
+
// getProperty(user, "email"); // ❌ Compile error — "email" not in keyof
|
|
43
|
+
|
|
44
|
+
// ✅ Default generic parameters
|
|
45
|
+
function createState<T = string>(initial: T): { value: T; set: (v: T) => void } {
|
|
46
|
+
let value = initial;
|
|
47
|
+
return { value, set: (v) => { value = v; } };
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Discriminated Unions (The Most Useful Pattern)
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
// ✅ Tagged unions — TypeScript narrows automatically
|
|
57
|
+
type Result<T, E = Error> =
|
|
58
|
+
| { success: true; data: T }
|
|
59
|
+
| { success: false; error: E };
|
|
60
|
+
|
|
61
|
+
function divide(a: number, b: number): Result<number, string> {
|
|
62
|
+
if (b === 0) return { success: false, error: "Division by zero" };
|
|
63
|
+
return { success: true, data: a / b };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const result = divide(10, 3);
|
|
67
|
+
if (result.success) {
|
|
68
|
+
console.log(result.data); // TypeScript KNOWS data exists
|
|
69
|
+
} else {
|
|
70
|
+
console.log(result.error); // TypeScript KNOWS error exists
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ✅ State machines with discriminated unions
|
|
74
|
+
type RequestState<T> =
|
|
75
|
+
| { status: "idle" }
|
|
76
|
+
| { status: "loading" }
|
|
77
|
+
| { status: "success"; data: T }
|
|
78
|
+
| { status: "error"; error: Error };
|
|
79
|
+
|
|
80
|
+
function renderUser(state: RequestState<User>) {
|
|
81
|
+
switch (state.status) {
|
|
82
|
+
case "idle": return <p>Click to load</p>;
|
|
83
|
+
case "loading": return <Spinner />;
|
|
84
|
+
case "success": return <UserCard user={state.data} />;
|
|
85
|
+
case "error": return <ErrorBanner error={state.error} />;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// ✅ TypeScript ensures ALL cases are handled (exhaustive checking)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Conditional Types
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
// ✅ Type-level if/else
|
|
97
|
+
type IsString<T> = T extends string ? true : false;
|
|
98
|
+
|
|
99
|
+
type A = IsString<"hello">; // true
|
|
100
|
+
type B = IsString<42>; // false
|
|
101
|
+
|
|
102
|
+
// ✅ Extract return type of async functions
|
|
103
|
+
type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;
|
|
104
|
+
|
|
105
|
+
type UserData = UnwrapPromise<Promise<{ name: string }>>;
|
|
106
|
+
// → { name: string }
|
|
107
|
+
|
|
108
|
+
// ✅ Practical: API response type extraction
|
|
109
|
+
type ApiResponse<T> = T extends (...args: any[]) => Promise<infer R> ? R : never;
|
|
110
|
+
|
|
111
|
+
declare function getUsers(): Promise<User[]>;
|
|
112
|
+
type Users = ApiResponse<typeof getUsers>; // User[]
|
|
113
|
+
|
|
114
|
+
// ✅ Distributive conditional types
|
|
115
|
+
type NonNullable<T> = T extends null | undefined ? never : T;
|
|
116
|
+
|
|
117
|
+
type Clean = NonNullable<string | null | undefined>; // string
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## Mapped Types
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
// ✅ Transform every property of a type
|
|
126
|
+
type Readonly<T> = { readonly [K in keyof T]: T[K] };
|
|
127
|
+
type Partial<T> = { [K in keyof T]?: T[K] };
|
|
128
|
+
type Required<T> = { [K in keyof T]-?: T[K] };
|
|
129
|
+
|
|
130
|
+
// ✅ Practical: Create a "form touched" state
|
|
131
|
+
type TouchedFields<T> = { [K in keyof T]: boolean };
|
|
132
|
+
|
|
133
|
+
interface LoginForm {
|
|
134
|
+
email: string;
|
|
135
|
+
password: string;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
type LoginTouched = TouchedFields<LoginForm>;
|
|
139
|
+
// → { email: boolean; password: boolean }
|
|
140
|
+
|
|
141
|
+
// ✅ Key remapping with `as`
|
|
142
|
+
type Getters<T> = {
|
|
143
|
+
[K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
type UserGetters = Getters<{ name: string; age: number }>;
|
|
147
|
+
// → { getName: () => string; getAge: () => number }
|
|
148
|
+
|
|
149
|
+
// ✅ Filter keys by value type
|
|
150
|
+
type StringKeys<T> = {
|
|
151
|
+
[K in keyof T as T[K] extends string ? K : never]: T[K];
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
type OnlyStrings = StringKeys<{ name: string; age: number; email: string }>;
|
|
155
|
+
// → { name: string; email: string }
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Template Literal Types
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
// ✅ Type-safe string patterns
|
|
164
|
+
type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
|
|
165
|
+
type APIRoute = `/api/${string}`;
|
|
166
|
+
type EventName = `on${Capitalize<string>}`;
|
|
167
|
+
|
|
168
|
+
// ✅ Practical: CSS unit types
|
|
169
|
+
type CSSUnit = "px" | "rem" | "em" | "vh" | "vw" | "%";
|
|
170
|
+
type CSSValue = `${number}${CSSUnit}`;
|
|
171
|
+
|
|
172
|
+
const width: CSSValue = "100px"; // ✅
|
|
173
|
+
// const bad: CSSValue = "100"; // ❌ Compile error
|
|
174
|
+
|
|
175
|
+
// ✅ Route parameter extraction
|
|
176
|
+
type ExtractParams<T extends string> =
|
|
177
|
+
T extends `${string}:${infer Param}/${infer Rest}`
|
|
178
|
+
? Param | ExtractParams<Rest>
|
|
179
|
+
: T extends `${string}:${infer Param}`
|
|
180
|
+
? Param
|
|
181
|
+
: never;
|
|
182
|
+
|
|
183
|
+
type UserRouteParams = ExtractParams<"/users/:userId/posts/:postId">;
|
|
184
|
+
// → "userId" | "postId"
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## The `satisfies` Operator (TS 5.0+)
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
// ✅ satisfies checks the type WITHOUT widening it
|
|
193
|
+
type ColorMap = Record<string, [number, number, number] | string>;
|
|
194
|
+
|
|
195
|
+
// With `as` — loses specificity
|
|
196
|
+
const colorsAs = {
|
|
197
|
+
red: [255, 0, 0],
|
|
198
|
+
green: "#00ff00",
|
|
199
|
+
} as ColorMap;
|
|
200
|
+
colorsAs.red.map(x => x); // ❌ Error: string | number[] has no .map
|
|
201
|
+
|
|
202
|
+
// With `satisfies` — keeps literal types
|
|
203
|
+
const colors = {
|
|
204
|
+
red: [255, 0, 0],
|
|
205
|
+
green: "#00ff00",
|
|
206
|
+
} satisfies ColorMap;
|
|
207
|
+
colors.red.map(x => x); // ✅ TypeScript knows it's a tuple
|
|
208
|
+
colors.green.toUpperCase(); // ✅ TypeScript knows it's a string
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Branded / Nominal Types
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
// ✅ Prevent accidental mixing of same-shaped types
|
|
217
|
+
type UserId = string & { readonly __brand: "UserId" };
|
|
218
|
+
type OrderId = string & { readonly __brand: "OrderId" };
|
|
219
|
+
|
|
220
|
+
function createUserId(id: string): UserId { return id as UserId; }
|
|
221
|
+
function createOrderId(id: string): OrderId { return id as OrderId; }
|
|
222
|
+
|
|
223
|
+
function getUser(id: UserId): Promise<User> { ... }
|
|
224
|
+
|
|
225
|
+
const userId = createUserId("user_123");
|
|
226
|
+
const orderId = createOrderId("order_456");
|
|
227
|
+
|
|
228
|
+
getUser(userId); // ✅ Correct
|
|
229
|
+
// getUser(orderId); // ❌ Compile error — OrderId is not UserId
|
|
230
|
+
|
|
231
|
+
// ✅ Branded number types
|
|
232
|
+
type Cents = number & { readonly __brand: "Cents" };
|
|
233
|
+
type Dollars = number & { readonly __brand: "Dollars" };
|
|
234
|
+
|
|
235
|
+
function centsToDollars(cents: Cents): Dollars {
|
|
236
|
+
return (cents / 100) as Dollars;
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Utility Types (Know the Built-ins)
|
|
243
|
+
|
|
244
|
+
```typescript
|
|
245
|
+
// Don't reimplement what TypeScript provides
|
|
246
|
+
|
|
247
|
+
Pick<T, K> // Select specific keys
|
|
248
|
+
Omit<T, K> // Remove specific keys
|
|
249
|
+
Partial<T> // All properties optional
|
|
250
|
+
Required<T> // All properties required
|
|
251
|
+
Readonly<T> // All properties readonly
|
|
252
|
+
Record<K, V> // Object with keys K and values V
|
|
253
|
+
Extract<T, U> // Members of T assignable to U
|
|
254
|
+
Exclude<T, U> // Members of T NOT assignable to U
|
|
255
|
+
NonNullable<T> // Remove null and undefined
|
|
256
|
+
ReturnType<T> // Return type of a function
|
|
257
|
+
Parameters<T> // Parameter types of a function as tuple
|
|
258
|
+
Awaited<T> // Unwrap Promise<T> recursively
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
---
|
|
262
|
+
|
|
263
|
+
## Anti-Patterns
|
|
264
|
+
|
|
265
|
+
```
|
|
266
|
+
❌ `as any` — hides runtime crashes. Fix the type or use `as unknown as T` with a comment.
|
|
267
|
+
❌ `// @ts-ignore` — use `// @ts-expect-error` with a reason comment instead.
|
|
268
|
+
❌ `interface` for unions — interfaces can't express `A | B`. Use `type`.
|
|
269
|
+
❌ Overusing generics — if <T> is only used once, you probably don't need it.
|
|
270
|
+
❌ `enum` for new code — use `as const` objects or union types instead.
|
|
271
|
+
❌ Type assertions in tests — use proper type guards or schema validation.
|
|
272
|
+
❌ `!` (non-null assertion) — it's a lie. Use optional chaining or narrowing.
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
// ❌ BAD: Non-null assertion
|
|
277
|
+
const element = document.getElementById("app")!;
|
|
278
|
+
|
|
279
|
+
// ✅ GOOD: Narrowing
|
|
280
|
+
const element = document.getElementById("app");
|
|
281
|
+
if (!element) throw new Error("Missing #app element");
|
|
282
|
+
// element is now guaranteed non-null
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
286
|
|
|
287
287
|
|
|
288
288
|
---
|
|
@@ -324,4 +324,12 @@ Review these questions before confirming output:
|
|
|
324
324
|
|
|
325
325
|
**CRITICAL:** You must follow a strict "evidence-based closeout" state machine.
|
|
326
326
|
- ❌ **Forbidden:** Declaring a task complete because the output "looks correct."
|
|
327
|
-
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
327
|
+
- ✅ **Required:** You are explicitly forbidden from finalizing any task without providing **concrete evidence** (terminal output, passing tests, compile success, or equivalent proof) that your output works as intended.
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
## Pre-Flight Checklist
|
|
331
|
+
- [ ] Have I reviewed the user's specific constraints and requests?
|
|
332
|
+
- [ ] Have I checked the environment for relevant existing implementations?
|
|
333
|
+
|
|
334
|
+
## VBC Protocol (Verification-Before-Completion)
|
|
335
|
+
You MUST verify existing code signatures and variables before attempting to modify or call them. No hallucination is permitted.
|