AgentSkillsCN

typescript

在前端与后端代码库中严格贯彻 TypeScript 类型约束。 适用场景:编写新服务、定义数据传输对象(DTO)、声明接口、实现类型守卫、调试类型错误,或在 API 边界处确保类型安全时使用。

SKILL.md
--- frontmatter
name: typescript
description: |
  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.
allowed-tools: Read, Edit, Write, Glob, Grep, Bash

TypeScript Skill

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.

Quick Start

Define Entity Types

typescript
// 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[];
}

Extend Express Request for Auth

typescript
// backend/src/middleware/authMiddleware.ts
export interface AuthenticatedRequest extends Request {
  user?: { email: string };
  userId?: number;
  adminId?: number;
  role?: string;
}

Database Row Mapping

typescript
// 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,
});

Key Concepts

ConceptUsageExample
Discriminated unionsCMS block typestype: 'hero' | 'features'
Optional vs nullableAPI fieldsfield?: T vs field: T | null
Record typesJSONB columnsRecord<string, any>
Interface extensionAuth middlewareextends Request
Generic functionsReusable hooks<T extends Record<string, any>>

Common Patterns

Discriminated Union for CMS Blocks

When: Multiple content types share a structure but have different shapes

typescript
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
}

Service Return Types

When: Every service function must declare its Promise type

typescript
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;
}

See Also

  • patterns - Type patterns and idioms
  • types - Type definitions and contracts
  • modules - Module organization
  • errors - Error handling patterns

Related Skills

  • See the express skill for route typing and middleware
  • See the react skill for component prop typing
  • See the zod skill for runtime validation schemas
  • See the postgresql skill for database query typing
  • See the tanstack-query skill for typed data fetching