Loading...
Loading...
TypeScript best practices, type safety, and toolchain standards. Use when: - Writing or reviewing TypeScript code - Setting up TypeScript projects or tsconfig - Choosing state management patterns - Configuring build tools (tsup, Vitest) - Avoiding type gymnastics or any-abuse Keywords: TypeScript, tsconfig, strict mode, no-any, pnpm, Vitest, tsup, TanStack Query, discriminated unions, type safety, ESLint
npx skill4agent add phrazzld/claude-config typescript-excellenceany// Unknown for external data
function parse(input: unknown): User { ... }
// Union for specific options
type Status = 'loading' | 'success' | 'error';
// Generics for reusable code
function first<T>(arr: T[]): T | undefined { ... }
// Type assertion as last resort (with runtime check)
if (isUser(data)) { return data as User; }{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"noUncheckedIndexedAccess": true,
"exactOptionalPropertyTypes": true
}
}src/
features/
auth/
components/
hooks/
api.ts
types.ts
index.ts # Barrel: controlled exports
orders/
...
shared/
ui/
utils/@features/*@shared/*../../../../const { data, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});type AuthState =
| { status: 'idle' }
| { status: 'loading' }
| { status: 'authenticated'; user: User }
| { status: 'error'; error: AppError };async function fetchUser(id: string): Promise<User> {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new ApiError(res.status, await res.text());
return res.json();
} catch (error) {
throw new AppError('Failed to fetch user', { cause: error });
}
}AbortControllerfinally| Tool | Purpose |
|---|---|
| pnpm | Package manager (declare in |
| Vitest | Testing (unit/integration/e2e) |
| tsup | Builds (ESM + CJS + .d.ts) |
| ESLint | Linting ( |
| Prettier | Formatting |
useStateuseEffect/controllers/services/modelseslint-disable