.claude/skills/typescript/SKILL.md
Enforces strict TypeScript types across frontend and backend codebases. Use when: Writing new services, DTOs, interfaces, type guards, debugging type errors, or ensuring type safety at API boundaries.
npx skillsauth add kaxuna1/ecomsite typescriptInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Strict TypeScript configuration for full-stack e-commerce platform. Backend uses strict: true with Express/PostgreSQL, frontend uses strict: true with Vite/React. Types are defined separately in each codebase but follow identical naming conventions for API contracts.
// backend/src/types/index.ts
export interface Product {
id: number;
name: string;
price: number;
salePrice?: number | null; // Optional AND nullable
categories: string[]; // Arrays typed explicitly
customAttributes?: Record<string, any>; // Flexible JSONB
}
// Request payload - all fields explicit
export interface ProductPayload {
name: string;
price: number;
salePrice?: number; // Optional on create
categories: string[];
}
// backend/src/middleware/authMiddleware.ts
export interface AuthenticatedRequest extends Request {
user?: { email: string };
userId?: number;
adminId?: number;
role?: string;
}
// Convert snake_case DB rows to camelCase TypeScript
const mapProductFromDb = (row: any): Product => ({
id: row.id,
name: row.name,
salePrice: row.sale_price, // snake_case → camelCase
createdAt: row.created_at,
});
| Concept | Usage | Example |
|---------|-------|---------|
| Discriminated unions | CMS block types | type: 'hero' \| 'features' |
| Optional vs nullable | API fields | field?: T vs field: T \| null |
| Record types | JSONB columns | Record<string, any> |
| Interface extension | Auth middleware | extends Request |
| Generic functions | Reusable hooks | <T extends Record<string, any>> |
When: Multiple content types share a structure but have different shapes
export type BlockContent =
| { type: 'hero'; headline: string; imageUrl: string }
| { type: 'features'; items: FeatureItem[] }
| { type: 'products'; productIds: number[] };
// TypeScript narrows automatically
if (block.type === 'hero') {
console.log(block.headline); // Safe access
}
When: Every service function must declare its Promise type
export async function getProduct(id: number): Promise<Product | null> {
const result = await pool.query('SELECT * FROM products WHERE id = $1', [id]);
return result.rows[0] ? mapProductFromDb(result.rows[0]) : null;
}
tools
Zustand lightweight state management with persistence and middleware. Use when: managing client-side state (cart, auth, UI preferences), replacing React Context with simpler API, accessing state outside React components, implementing localStorage persistence
development
Zod schema validation and TypeScript integration for runtime type safety. Use when: Validating API payloads, form inputs, environment variables, or any external data boundaries where TypeScript types alone cannot guarantee safety.
tools
Configures Vite 5.x build tool, dev server, and frontend asset optimization for the Luxia e-commerce platform. Use when: configuring builds, adding environment variables, optimizing bundle size, setting up testing, debugging HMR issues, or adding Vite plugins.
development
Manages server state, API caching, and data fetching with TanStack React Query v5. Use when: Fetching API data, managing server state, polling for updates, handling mutations with cache invalidation.