start-vibing 2.0.11 → 2.0.13
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/README.md +177 -177
- package/dist/cli.js +19 -2
- package/package.json +42 -42
- package/template/.claude/CLAUDE.md +174 -174
- package/template/.claude/agents/01-orchestration/agent-selector.md +130 -130
- package/template/.claude/agents/01-orchestration/checkpoint-manager.md +142 -142
- package/template/.claude/agents/01-orchestration/context-manager.md +138 -138
- package/template/.claude/agents/01-orchestration/error-recovery.md +182 -182
- package/template/.claude/agents/01-orchestration/orchestrator.md +114 -114
- package/template/.claude/agents/01-orchestration/parallel-coordinator.md +141 -141
- package/template/.claude/agents/01-orchestration/task-decomposer.md +121 -121
- package/template/.claude/agents/01-orchestration/workflow-router.md +114 -114
- package/template/.claude/agents/02-typescript/bun-runtime-expert.md +197 -197
- package/template/.claude/agents/02-typescript/esm-resolver.md +193 -193
- package/template/.claude/agents/02-typescript/import-alias-enforcer.md +158 -158
- package/template/.claude/agents/02-typescript/ts-generics-helper.md +183 -183
- package/template/.claude/agents/02-typescript/ts-migration-helper.md +238 -238
- package/template/.claude/agents/02-typescript/ts-strict-checker.md +180 -180
- package/template/.claude/agents/02-typescript/ts-types-analyzer.md +199 -199
- package/template/.claude/agents/02-typescript/type-definition-writer.md +187 -187
- package/template/.claude/agents/02-typescript/zod-schema-designer.md +212 -212
- package/template/.claude/agents/02-typescript/zod-validator.md +158 -158
- package/template/.claude/agents/03-testing/playwright-assertions.md +265 -265
- package/template/.claude/agents/03-testing/playwright-e2e.md +247 -247
- package/template/.claude/agents/03-testing/playwright-fixtures.md +234 -234
- package/template/.claude/agents/03-testing/playwright-multi-viewport.md +256 -256
- package/template/.claude/agents/03-testing/playwright-page-objects.md +247 -247
- package/template/.claude/agents/03-testing/test-cleanup-manager.md +248 -248
- package/template/.claude/agents/03-testing/test-data-generator.md +254 -254
- package/template/.claude/agents/03-testing/tester-integration.md +278 -278
- package/template/.claude/agents/03-testing/tester-unit.md +207 -207
- package/template/.claude/agents/03-testing/vitest-config.md +287 -287
- package/template/.claude/agents/04-docker/container-health.md +255 -255
- package/template/.claude/agents/04-docker/deployment-validator.md +225 -225
- package/template/.claude/agents/04-docker/docker-compose-designer.md +281 -281
- package/template/.claude/agents/04-docker/docker-env-manager.md +235 -235
- package/template/.claude/agents/04-docker/docker-multi-stage.md +241 -241
- package/template/.claude/agents/04-docker/dockerfile-optimizer.md +208 -208
- package/template/.claude/agents/05-database/database-seeder.md +273 -273
- package/template/.claude/agents/05-database/mongodb-query-optimizer.md +230 -230
- package/template/.claude/agents/05-database/mongoose-aggregation.md +306 -306
- package/template/.claude/agents/05-database/mongoose-index-optimizer.md +182 -182
- package/template/.claude/agents/05-database/mongoose-schema-designer.md +267 -267
- package/template/.claude/agents/06-security/auth-session-validator.md +68 -68
- package/template/.claude/agents/06-security/input-sanitizer.md +80 -80
- package/template/.claude/agents/06-security/owasp-checker.md +97 -97
- package/template/.claude/agents/06-security/permission-auditor.md +100 -100
- package/template/.claude/agents/06-security/security-auditor.md +84 -84
- package/template/.claude/agents/06-security/sensitive-data-scanner.md +83 -83
- package/template/.claude/agents/07-documentation/api-documenter.md +136 -136
- package/template/.claude/agents/07-documentation/changelog-manager.md +105 -105
- package/template/.claude/agents/07-documentation/documenter.md +76 -76
- package/template/.claude/agents/07-documentation/domain-updater.md +81 -81
- package/template/.claude/agents/07-documentation/jsdoc-generator.md +114 -114
- package/template/.claude/agents/07-documentation/readme-generator.md +135 -135
- package/template/.claude/agents/08-git/branch-manager.md +58 -58
- package/template/.claude/agents/08-git/commit-manager.md +63 -63
- package/template/.claude/agents/08-git/pr-creator.md +76 -76
- package/template/.claude/agents/09-quality/code-reviewer.md +71 -71
- package/template/.claude/agents/09-quality/quality-checker.md +67 -67
- package/template/.claude/agents/10-research/best-practices-finder.md +89 -89
- package/template/.claude/agents/10-research/competitor-analyzer.md +106 -106
- package/template/.claude/agents/10-research/pattern-researcher.md +93 -93
- package/template/.claude/agents/10-research/research-cache-manager.md +76 -76
- package/template/.claude/agents/10-research/research-web.md +98 -98
- package/template/.claude/agents/10-research/tech-evaluator.md +101 -101
- package/template/.claude/agents/11-ui-ux/accessibility-auditor.md +136 -136
- package/template/.claude/agents/11-ui-ux/design-system-enforcer.md +125 -125
- package/template/.claude/agents/11-ui-ux/skeleton-generator.md +118 -118
- package/template/.claude/agents/11-ui-ux/ui-desktop.md +132 -132
- package/template/.claude/agents/11-ui-ux/ui-mobile.md +98 -98
- package/template/.claude/agents/11-ui-ux/ui-tablet.md +110 -110
- package/template/.claude/agents/12-performance/api-latency-analyzer.md +156 -156
- package/template/.claude/agents/12-performance/bundle-analyzer.md +113 -113
- package/template/.claude/agents/12-performance/memory-leak-detector.md +137 -137
- package/template/.claude/agents/12-performance/performance-profiler.md +115 -115
- package/template/.claude/agents/12-performance/query-optimizer.md +124 -124
- package/template/.claude/agents/12-performance/render-optimizer.md +154 -154
- package/template/.claude/agents/13-debugging/build-error-fixer.md +207 -207
- package/template/.claude/agents/13-debugging/debugger.md +149 -149
- package/template/.claude/agents/13-debugging/error-stack-analyzer.md +141 -141
- package/template/.claude/agents/13-debugging/network-debugger.md +208 -208
- package/template/.claude/agents/13-debugging/runtime-error-fixer.md +181 -181
- package/template/.claude/agents/13-debugging/type-error-resolver.md +185 -185
- package/template/.claude/agents/14-validation/final-validator.md +93 -93
- package/template/.claude/agents/_backup/analyzer.md +134 -134
- package/template/.claude/agents/_backup/code-reviewer.md +279 -279
- package/template/.claude/agents/_backup/commit-manager.md +219 -219
- package/template/.claude/agents/_backup/debugger.md +280 -280
- package/template/.claude/agents/_backup/documenter.md +237 -237
- package/template/.claude/agents/_backup/domain-updater.md +197 -197
- package/template/.claude/agents/_backup/final-validator.md +169 -169
- package/template/.claude/agents/_backup/orchestrator.md +149 -149
- package/template/.claude/agents/_backup/performance.md +232 -232
- package/template/.claude/agents/_backup/quality-checker.md +240 -240
- package/template/.claude/agents/_backup/research.md +315 -315
- package/template/.claude/agents/_backup/security-auditor.md +192 -192
- package/template/.claude/agents/_backup/tester.md +566 -566
- package/template/.claude/agents/_backup/ui-ux-reviewer.md +247 -247
- package/template/.claude/config/README.md +30 -30
- package/template/.claude/config/mcp-config.json +344 -344
- package/template/.claude/config/project-config.json +53 -53
- package/template/.claude/config/quality-gates.json +46 -46
- package/template/.claude/config/security-rules.json +45 -45
- package/template/.claude/config/testing-config.json +164 -164
- package/template/.claude/hooks/SETUP.md +126 -126
- package/template/.claude/hooks/run-hook.ts +176 -176
- package/template/.claude/hooks/stop-validator.ts +914 -824
- package/template/.claude/hooks/user-prompt-submit.ts +886 -886
- package/template/.claude/scripts/mcp-quick-install.ts +151 -151
- package/template/.claude/scripts/setup-mcps.ts +651 -651
- package/template/.claude/settings.json +275 -275
- package/template/.claude/skills/bun-runtime/SKILL.md +430 -430
- package/template/.claude/skills/codebase-knowledge/domains/claude-system.md +431 -431
- package/template/.claude/skills/codebase-knowledge/domains/mcp-integration.md +295 -295
- package/template/.claude/skills/debugging-patterns/SKILL.md +485 -485
- package/template/.claude/skills/docker-patterns/SKILL.md +555 -555
- package/template/.claude/skills/git-workflow/SKILL.md +454 -454
- package/template/.claude/skills/mongoose-patterns/SKILL.md +499 -499
- package/template/.claude/skills/nextjs-app-router/SKILL.md +327 -327
- package/template/.claude/skills/performance-patterns/SKILL.md +547 -547
- package/template/.claude/skills/playwright-automation/SKILL.md +438 -438
- package/template/.claude/skills/react-patterns/SKILL.md +389 -389
- package/template/.claude/skills/research-cache/SKILL.md +222 -222
- package/template/.claude/skills/shadcn-ui/SKILL.md +511 -511
- package/template/.claude/skills/tailwind-patterns/SKILL.md +465 -465
- package/template/.claude/skills/test-coverage/SKILL.md +467 -467
- package/template/.claude/skills/trpc-api/SKILL.md +434 -434
- package/template/.claude/skills/typescript-strict/SKILL.md +367 -367
- package/template/.claude/skills/zod-validation/SKILL.md +403 -403
- package/template/CLAUDE.md +117 -117
|
@@ -1,367 +1,367 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: typescript-strict
|
|
3
|
-
description: TypeScript strict mode patterns and best practices. Index access, literal types, null checks, generics, type inference. Use when working with TypeScript files.
|
|
4
|
-
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# TypeScript Strict - Type Safety Patterns
|
|
8
|
-
|
|
9
|
-
## Purpose
|
|
10
|
-
|
|
11
|
-
Expert guidance for TypeScript strict mode:
|
|
12
|
-
|
|
13
|
-
- **Strict Null Checks** - Handle undefined/null properly
|
|
14
|
-
- **Index Access** - Safe property access patterns
|
|
15
|
-
- **Literal Types** - Const assertions and narrowing
|
|
16
|
-
- **Generics** - Type-safe reusable patterns
|
|
17
|
-
- **Type Guards** - Runtime type validation
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Critical tsconfig.json
|
|
22
|
-
|
|
23
|
-
```json
|
|
24
|
-
{
|
|
25
|
-
"compilerOptions": {
|
|
26
|
-
"strict": true,
|
|
27
|
-
"noUncheckedIndexedAccess": true,
|
|
28
|
-
"noImplicitAny": true,
|
|
29
|
-
"strictNullChecks": true,
|
|
30
|
-
"strictFunctionTypes": true,
|
|
31
|
-
"noImplicitReturns": true,
|
|
32
|
-
"noFallthroughCasesInSwitch": true,
|
|
33
|
-
"exactOptionalPropertyTypes": true,
|
|
34
|
-
"noPropertyAccessFromIndexSignature": true
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
## Index Access Patterns
|
|
42
|
-
|
|
43
|
-
### Environment Variables
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
// WRONG - TS7053
|
|
47
|
-
const port = process.env.PORT;
|
|
48
|
-
|
|
49
|
-
// CORRECT - Use bracket notation
|
|
50
|
-
const port = process.env['PORT'];
|
|
51
|
-
const host = process.env['HOST'] ?? 'localhost';
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Object Property Access
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
interface Config {
|
|
58
|
-
[key: string]: string | undefined;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const config: Config = { api: 'https://api.example.com' };
|
|
62
|
-
|
|
63
|
-
// WRONG - Direct access
|
|
64
|
-
const url = config.api;
|
|
65
|
-
|
|
66
|
-
// CORRECT - Bracket access with check
|
|
67
|
-
const url = config['api'];
|
|
68
|
-
if (url) {
|
|
69
|
-
fetch(url);
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Array Access
|
|
74
|
-
|
|
75
|
-
```typescript
|
|
76
|
-
const items = ['a', 'b', 'c'];
|
|
77
|
-
|
|
78
|
-
// WRONG - Could be undefined
|
|
79
|
-
const first = items[0].toUpperCase();
|
|
80
|
-
|
|
81
|
-
// CORRECT - Check first
|
|
82
|
-
const first = items[0];
|
|
83
|
-
if (first) {
|
|
84
|
-
console.log(first.toUpperCase());
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Or use non-null assertion if certain
|
|
88
|
-
const guaranteed = items[0]!;
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
---
|
|
92
|
-
|
|
93
|
-
## Literal Types & Const Assertions
|
|
94
|
-
|
|
95
|
-
### String Literals
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// WRONG - Type is string
|
|
99
|
-
const status = 'pending';
|
|
100
|
-
|
|
101
|
-
// CORRECT - Literal type
|
|
102
|
-
const status = 'pending' as const;
|
|
103
|
-
// type: "pending"
|
|
104
|
-
|
|
105
|
-
// Object with literals
|
|
106
|
-
const config = {
|
|
107
|
-
mode: 'production' as const,
|
|
108
|
-
level: 'high' as const,
|
|
109
|
-
};
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Object Literals
|
|
113
|
-
|
|
114
|
-
```typescript
|
|
115
|
-
// WRONG - Types are widened
|
|
116
|
-
const endpoints = {
|
|
117
|
-
users: '/api/users',
|
|
118
|
-
posts: '/api/posts',
|
|
119
|
-
};
|
|
120
|
-
// type: { users: string; posts: string }
|
|
121
|
-
|
|
122
|
-
// CORRECT - Exact types
|
|
123
|
-
const endpoints = {
|
|
124
|
-
users: '/api/users',
|
|
125
|
-
posts: '/api/posts',
|
|
126
|
-
} as const;
|
|
127
|
-
// type: { readonly users: "/api/users"; readonly posts: "/api/posts" }
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Discriminated Unions
|
|
131
|
-
|
|
132
|
-
```typescript
|
|
133
|
-
type Result<T> = { success: true; data: T } | { success: false; error: string };
|
|
134
|
-
|
|
135
|
-
function handleResult<T>(result: Result<T>) {
|
|
136
|
-
if (result.success) {
|
|
137
|
-
// TypeScript knows result.data exists here
|
|
138
|
-
return result.data;
|
|
139
|
-
} else {
|
|
140
|
-
// TypeScript knows result.error exists here
|
|
141
|
-
throw new Error(result.error);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
---
|
|
147
|
-
|
|
148
|
-
## Null & Undefined Handling
|
|
149
|
-
|
|
150
|
-
### Optional Chaining
|
|
151
|
-
|
|
152
|
-
```typescript
|
|
153
|
-
interface User {
|
|
154
|
-
profile?: {
|
|
155
|
-
avatar?: string;
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// CORRECT - Optional chaining
|
|
160
|
-
const avatar = user.profile?.avatar ?? '/default.png';
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
### Nullish Coalescing
|
|
164
|
-
|
|
165
|
-
```typescript
|
|
166
|
-
// WRONG - || treats 0, '', false as falsy
|
|
167
|
-
const count = input || 10;
|
|
168
|
-
|
|
169
|
-
// CORRECT - ?? only treats null/undefined as nullish
|
|
170
|
-
const count = input ?? 10;
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
### Type Guards
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
// Custom type guard
|
|
177
|
-
function isUser(value: unknown): value is User {
|
|
178
|
-
return typeof value === 'object' && value !== null && 'id' in value && 'email' in value;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Usage
|
|
182
|
-
function processData(data: unknown) {
|
|
183
|
-
if (isUser(data)) {
|
|
184
|
-
// TypeScript knows data is User here
|
|
185
|
-
console.log(data.email);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### Assertion Functions
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
function assertDefined<T>(value: T | undefined | null, message: string): asserts value is T {
|
|
194
|
-
if (value === undefined || value === null) {
|
|
195
|
-
throw new Error(message);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Usage
|
|
200
|
-
const user = await getUser(id);
|
|
201
|
-
assertDefined(user, `User ${id} not found`);
|
|
202
|
-
// user is guaranteed to be defined after this
|
|
203
|
-
console.log(user.name);
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
---
|
|
207
|
-
|
|
208
|
-
## Generic Patterns
|
|
209
|
-
|
|
210
|
-
### Constrained Generics
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
// Ensure T has an id property
|
|
214
|
-
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
|
|
215
|
-
return items.find((item) => item.id === id);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Works with any type that has id
|
|
219
|
-
interface User {
|
|
220
|
-
id: string;
|
|
221
|
-
name: string;
|
|
222
|
-
}
|
|
223
|
-
interface Post {
|
|
224
|
-
id: string;
|
|
225
|
-
title: string;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
findById(users, '123'); // T is User
|
|
229
|
-
findById(posts, '456'); // T is Post
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
### Infer Return Type
|
|
233
|
-
|
|
234
|
-
```typescript
|
|
235
|
-
// Infer return type from callback
|
|
236
|
-
function createFetcher<T>(fetcher: () => Promise<T>) {
|
|
237
|
-
return {
|
|
238
|
-
fetch: fetcher,
|
|
239
|
-
refetch: () => fetcher(),
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// T is automatically inferred
|
|
244
|
-
const userFetcher = createFetcher(async () => {
|
|
245
|
-
const res = await fetch('/api/user');
|
|
246
|
-
return res.json() as Promise<User>;
|
|
247
|
-
});
|
|
248
|
-
// userFetcher.fetch() returns Promise<User>
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### Mapped Types
|
|
252
|
-
|
|
253
|
-
```typescript
|
|
254
|
-
// Make all properties optional
|
|
255
|
-
type Partial<T> = {
|
|
256
|
-
[P in keyof T]?: T[P];
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
// Make all properties readonly
|
|
260
|
-
type Readonly<T> = {
|
|
261
|
-
readonly [P in keyof T]: T[P];
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
// Pick specific properties
|
|
265
|
-
type Pick<T, K extends keyof T> = {
|
|
266
|
-
[P in K]: T[P];
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
// Custom: Make specific properties required
|
|
270
|
-
type RequireFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
|
|
275
|
-
## Utility Types
|
|
276
|
-
|
|
277
|
-
```typescript
|
|
278
|
-
// Exclude null/undefined
|
|
279
|
-
type NonNullable<T> = T extends null | undefined ? never : T;
|
|
280
|
-
|
|
281
|
-
// Extract function return type
|
|
282
|
-
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
|
|
283
|
-
|
|
284
|
-
// Extract function parameters
|
|
285
|
-
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
|
|
286
|
-
|
|
287
|
-
// Usage
|
|
288
|
-
type UserSchema = z.infer<typeof userSchema>;
|
|
289
|
-
type ApiResponse = Awaited<ReturnType<typeof fetchUser>>;
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
|
-
## Common Errors & Fixes
|
|
295
|
-
|
|
296
|
-
### TS2532: Object is possibly 'undefined'
|
|
297
|
-
|
|
298
|
-
```typescript
|
|
299
|
-
// ERROR
|
|
300
|
-
const name = user.profile.name;
|
|
301
|
-
|
|
302
|
-
// FIX - Optional chaining
|
|
303
|
-
const name = user.profile?.name ?? 'Unknown';
|
|
304
|
-
```
|
|
305
|
-
|
|
306
|
-
### TS2339: Property does not exist
|
|
307
|
-
|
|
308
|
-
```typescript
|
|
309
|
-
// ERROR
|
|
310
|
-
const env = process.env.NODE_ENV;
|
|
311
|
-
|
|
312
|
-
// FIX - Bracket access
|
|
313
|
-
const env = process.env['NODE_ENV'];
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
### TS7053: Index signature
|
|
317
|
-
|
|
318
|
-
```typescript
|
|
319
|
-
// ERROR
|
|
320
|
-
const value = obj[key];
|
|
321
|
-
|
|
322
|
-
// FIX - Type assertion or bracket notation
|
|
323
|
-
const value = (obj as Record<string, unknown>)[key];
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
---
|
|
327
|
-
|
|
328
|
-
## Agent Integration
|
|
329
|
-
|
|
330
|
-
This skill is used by:
|
|
331
|
-
|
|
332
|
-
- **ts-strict-checker** agent
|
|
333
|
-
- **ts-types-analyzer** agent
|
|
334
|
-
- **type-error-resolver** agent
|
|
335
|
-
- **quality-checker** for typecheck validation
|
|
336
|
-
|
|
337
|
-
---
|
|
338
|
-
|
|
339
|
-
## Commands
|
|
340
|
-
|
|
341
|
-
```bash
|
|
342
|
-
# Type check
|
|
343
|
-
bun run typecheck
|
|
344
|
-
bunx tsc --noEmit
|
|
345
|
-
|
|
346
|
-
# Check specific file
|
|
347
|
-
bunx tsc --noEmit path/to/file.ts
|
|
348
|
-
|
|
349
|
-
# Generate types
|
|
350
|
-
bunx tsc --declaration --emitDeclarationOnly
|
|
351
|
-
```
|
|
352
|
-
|
|
353
|
-
---
|
|
354
|
-
|
|
355
|
-
## FORBIDDEN
|
|
356
|
-
|
|
357
|
-
1. **`any` type** - Use `unknown` instead
|
|
358
|
-
2. **Non-null assertion without certainty** - Check first
|
|
359
|
-
3. **Type assertion to hide errors** - Fix the actual issue
|
|
360
|
-
4. **Ignoring strict errors** - Always fix properly
|
|
361
|
-
5. **`@ts-ignore` without explanation** - Use `@ts-expect-error` with comment
|
|
362
|
-
|
|
363
|
-
---
|
|
364
|
-
|
|
365
|
-
## Version
|
|
366
|
-
|
|
367
|
-
- **v1.0.0** - Initial implementation based on TypeScript 5.x strict patterns
|
|
1
|
+
---
|
|
2
|
+
name: typescript-strict
|
|
3
|
+
description: TypeScript strict mode patterns and best practices. Index access, literal types, null checks, generics, type inference. Use when working with TypeScript files.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TypeScript Strict - Type Safety Patterns
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Expert guidance for TypeScript strict mode:
|
|
12
|
+
|
|
13
|
+
- **Strict Null Checks** - Handle undefined/null properly
|
|
14
|
+
- **Index Access** - Safe property access patterns
|
|
15
|
+
- **Literal Types** - Const assertions and narrowing
|
|
16
|
+
- **Generics** - Type-safe reusable patterns
|
|
17
|
+
- **Type Guards** - Runtime type validation
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Critical tsconfig.json
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"compilerOptions": {
|
|
26
|
+
"strict": true,
|
|
27
|
+
"noUncheckedIndexedAccess": true,
|
|
28
|
+
"noImplicitAny": true,
|
|
29
|
+
"strictNullChecks": true,
|
|
30
|
+
"strictFunctionTypes": true,
|
|
31
|
+
"noImplicitReturns": true,
|
|
32
|
+
"noFallthroughCasesInSwitch": true,
|
|
33
|
+
"exactOptionalPropertyTypes": true,
|
|
34
|
+
"noPropertyAccessFromIndexSignature": true
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Index Access Patterns
|
|
42
|
+
|
|
43
|
+
### Environment Variables
|
|
44
|
+
|
|
45
|
+
```typescript
|
|
46
|
+
// WRONG - TS7053
|
|
47
|
+
const port = process.env.PORT;
|
|
48
|
+
|
|
49
|
+
// CORRECT - Use bracket notation
|
|
50
|
+
const port = process.env['PORT'];
|
|
51
|
+
const host = process.env['HOST'] ?? 'localhost';
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Object Property Access
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface Config {
|
|
58
|
+
[key: string]: string | undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const config: Config = { api: 'https://api.example.com' };
|
|
62
|
+
|
|
63
|
+
// WRONG - Direct access
|
|
64
|
+
const url = config.api;
|
|
65
|
+
|
|
66
|
+
// CORRECT - Bracket access with check
|
|
67
|
+
const url = config['api'];
|
|
68
|
+
if (url) {
|
|
69
|
+
fetch(url);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Array Access
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const items = ['a', 'b', 'c'];
|
|
77
|
+
|
|
78
|
+
// WRONG - Could be undefined
|
|
79
|
+
const first = items[0].toUpperCase();
|
|
80
|
+
|
|
81
|
+
// CORRECT - Check first
|
|
82
|
+
const first = items[0];
|
|
83
|
+
if (first) {
|
|
84
|
+
console.log(first.toUpperCase());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Or use non-null assertion if certain
|
|
88
|
+
const guaranteed = items[0]!;
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## Literal Types & Const Assertions
|
|
94
|
+
|
|
95
|
+
### String Literals
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// WRONG - Type is string
|
|
99
|
+
const status = 'pending';
|
|
100
|
+
|
|
101
|
+
// CORRECT - Literal type
|
|
102
|
+
const status = 'pending' as const;
|
|
103
|
+
// type: "pending"
|
|
104
|
+
|
|
105
|
+
// Object with literals
|
|
106
|
+
const config = {
|
|
107
|
+
mode: 'production' as const,
|
|
108
|
+
level: 'high' as const,
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Object Literals
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// WRONG - Types are widened
|
|
116
|
+
const endpoints = {
|
|
117
|
+
users: '/api/users',
|
|
118
|
+
posts: '/api/posts',
|
|
119
|
+
};
|
|
120
|
+
// type: { users: string; posts: string }
|
|
121
|
+
|
|
122
|
+
// CORRECT - Exact types
|
|
123
|
+
const endpoints = {
|
|
124
|
+
users: '/api/users',
|
|
125
|
+
posts: '/api/posts',
|
|
126
|
+
} as const;
|
|
127
|
+
// type: { readonly users: "/api/users"; readonly posts: "/api/posts" }
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Discriminated Unions
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
type Result<T> = { success: true; data: T } | { success: false; error: string };
|
|
134
|
+
|
|
135
|
+
function handleResult<T>(result: Result<T>) {
|
|
136
|
+
if (result.success) {
|
|
137
|
+
// TypeScript knows result.data exists here
|
|
138
|
+
return result.data;
|
|
139
|
+
} else {
|
|
140
|
+
// TypeScript knows result.error exists here
|
|
141
|
+
throw new Error(result.error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Null & Undefined Handling
|
|
149
|
+
|
|
150
|
+
### Optional Chaining
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
interface User {
|
|
154
|
+
profile?: {
|
|
155
|
+
avatar?: string;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// CORRECT - Optional chaining
|
|
160
|
+
const avatar = user.profile?.avatar ?? '/default.png';
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Nullish Coalescing
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
// WRONG - || treats 0, '', false as falsy
|
|
167
|
+
const count = input || 10;
|
|
168
|
+
|
|
169
|
+
// CORRECT - ?? only treats null/undefined as nullish
|
|
170
|
+
const count = input ?? 10;
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Type Guards
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
// Custom type guard
|
|
177
|
+
function isUser(value: unknown): value is User {
|
|
178
|
+
return typeof value === 'object' && value !== null && 'id' in value && 'email' in value;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Usage
|
|
182
|
+
function processData(data: unknown) {
|
|
183
|
+
if (isUser(data)) {
|
|
184
|
+
// TypeScript knows data is User here
|
|
185
|
+
console.log(data.email);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Assertion Functions
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
function assertDefined<T>(value: T | undefined | null, message: string): asserts value is T {
|
|
194
|
+
if (value === undefined || value === null) {
|
|
195
|
+
throw new Error(message);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Usage
|
|
200
|
+
const user = await getUser(id);
|
|
201
|
+
assertDefined(user, `User ${id} not found`);
|
|
202
|
+
// user is guaranteed to be defined after this
|
|
203
|
+
console.log(user.name);
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Generic Patterns
|
|
209
|
+
|
|
210
|
+
### Constrained Generics
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
// Ensure T has an id property
|
|
214
|
+
function findById<T extends { id: string }>(items: T[], id: string): T | undefined {
|
|
215
|
+
return items.find((item) => item.id === id);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Works with any type that has id
|
|
219
|
+
interface User {
|
|
220
|
+
id: string;
|
|
221
|
+
name: string;
|
|
222
|
+
}
|
|
223
|
+
interface Post {
|
|
224
|
+
id: string;
|
|
225
|
+
title: string;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
findById(users, '123'); // T is User
|
|
229
|
+
findById(posts, '456'); // T is Post
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### Infer Return Type
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
// Infer return type from callback
|
|
236
|
+
function createFetcher<T>(fetcher: () => Promise<T>) {
|
|
237
|
+
return {
|
|
238
|
+
fetch: fetcher,
|
|
239
|
+
refetch: () => fetcher(),
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// T is automatically inferred
|
|
244
|
+
const userFetcher = createFetcher(async () => {
|
|
245
|
+
const res = await fetch('/api/user');
|
|
246
|
+
return res.json() as Promise<User>;
|
|
247
|
+
});
|
|
248
|
+
// userFetcher.fetch() returns Promise<User>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### Mapped Types
|
|
252
|
+
|
|
253
|
+
```typescript
|
|
254
|
+
// Make all properties optional
|
|
255
|
+
type Partial<T> = {
|
|
256
|
+
[P in keyof T]?: T[P];
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Make all properties readonly
|
|
260
|
+
type Readonly<T> = {
|
|
261
|
+
readonly [P in keyof T]: T[P];
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// Pick specific properties
|
|
265
|
+
type Pick<T, K extends keyof T> = {
|
|
266
|
+
[P in K]: T[P];
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// Custom: Make specific properties required
|
|
270
|
+
type RequireFields<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
## Utility Types
|
|
276
|
+
|
|
277
|
+
```typescript
|
|
278
|
+
// Exclude null/undefined
|
|
279
|
+
type NonNullable<T> = T extends null | undefined ? never : T;
|
|
280
|
+
|
|
281
|
+
// Extract function return type
|
|
282
|
+
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
|
|
283
|
+
|
|
284
|
+
// Extract function parameters
|
|
285
|
+
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
|
|
286
|
+
|
|
287
|
+
// Usage
|
|
288
|
+
type UserSchema = z.infer<typeof userSchema>;
|
|
289
|
+
type ApiResponse = Awaited<ReturnType<typeof fetchUser>>;
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## Common Errors & Fixes
|
|
295
|
+
|
|
296
|
+
### TS2532: Object is possibly 'undefined'
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// ERROR
|
|
300
|
+
const name = user.profile.name;
|
|
301
|
+
|
|
302
|
+
// FIX - Optional chaining
|
|
303
|
+
const name = user.profile?.name ?? 'Unknown';
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### TS2339: Property does not exist
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
// ERROR
|
|
310
|
+
const env = process.env.NODE_ENV;
|
|
311
|
+
|
|
312
|
+
// FIX - Bracket access
|
|
313
|
+
const env = process.env['NODE_ENV'];
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### TS7053: Index signature
|
|
317
|
+
|
|
318
|
+
```typescript
|
|
319
|
+
// ERROR
|
|
320
|
+
const value = obj[key];
|
|
321
|
+
|
|
322
|
+
// FIX - Type assertion or bracket notation
|
|
323
|
+
const value = (obj as Record<string, unknown>)[key];
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Agent Integration
|
|
329
|
+
|
|
330
|
+
This skill is used by:
|
|
331
|
+
|
|
332
|
+
- **ts-strict-checker** agent
|
|
333
|
+
- **ts-types-analyzer** agent
|
|
334
|
+
- **type-error-resolver** agent
|
|
335
|
+
- **quality-checker** for typecheck validation
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## Commands
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Type check
|
|
343
|
+
bun run typecheck
|
|
344
|
+
bunx tsc --noEmit
|
|
345
|
+
|
|
346
|
+
# Check specific file
|
|
347
|
+
bunx tsc --noEmit path/to/file.ts
|
|
348
|
+
|
|
349
|
+
# Generate types
|
|
350
|
+
bunx tsc --declaration --emitDeclarationOnly
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## FORBIDDEN
|
|
356
|
+
|
|
357
|
+
1. **`any` type** - Use `unknown` instead
|
|
358
|
+
2. **Non-null assertion without certainty** - Check first
|
|
359
|
+
3. **Type assertion to hide errors** - Fix the actual issue
|
|
360
|
+
4. **Ignoring strict errors** - Always fix properly
|
|
361
|
+
5. **`@ts-ignore` without explanation** - Use `@ts-expect-error` with comment
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
## Version
|
|
366
|
+
|
|
367
|
+
- **v1.0.0** - Initial implementation based on TypeScript 5.x strict patterns
|