AgentSkillsCN

typescript-development

遵循 DHH/37signals 的开发理念,深入讲解 Ruby 与 Rails 8+ 的开发实践。内容包括 Ruby 常用语法、Hotwire、Solid Queue、Minitest、Gem 开发,以及 CLI 工具。在构建 Rails 应用、编写后台任务时,或当用户询问“如何添加 Hotwire?”或“Rails 中针对 X 的惯例是什么?”时,可加以应用。

SKILL.md
--- frontmatter
name: typescript-development
description: >-
  Covers TypeScript 5+ and JavaScript development with React ecosystem. Includes project setup,
  React 18+ components, Next.js 14+ App Router, modern ESM patterns, Zustand/React Query
  state management, React Hook Form with Zod validation, Tailwind CSS styling,
  Vitest/Playwright testing, and accessibility. Use when building React components, setting up
  Next.js, or when the user asks "how do I manage state?" or "what's the TypeScript way to do X?"

TypeScript Development

Comprehensive guide for modern TypeScript development with React ecosystem.

When to Use This Skill

  • Starting or configuring TypeScript projects
  • Building React components and applications
  • Working with Next.js 14+ and App Router
  • Implementing state management patterns
  • Building forms with validation
  • Integrating APIs and handling data fetching
  • Writing tests for TypeScript applications
  • Styling with Tailwind and CVA
  • Optimizing application performance
  • Implementing accessibility (a11y)
  • Building React Native mobile apps
  • Working with modern JavaScript (ESM)

Stack Overview

LayerDefaultAlternatives
LanguageTypeScript 5+JavaScript (ESM)
RuntimeNode.js 20+Bun, Deno
FrameworkNext.js 14+Vite, Remix
UI LibraryReact 18+-
State (Client)ZustandContext + Reducer
State (Server)React QuerySWR
FormsReact Hook Form + Zod-
StylingTailwind CSS + CVACSS Modules
TestingVitest + RTLJest
E2E TestingPlaywrightCypress
Package Managerpnpmnpm, yarn

Core Philosophy

  • Strict mode always - catch errors at compile time
  • Server Components by default - use Client Components only when needed
  • Type inference - let TypeScript infer when obvious
  • Server state is different - use React Query for API data
  • Accessibility is mandatory - not optional
  • Mobile-first responsive - design for small screens first
  • Measure before optimizing - profile, then fix

Quick Reference

Project Setup

json
// tsconfig.json essentials
{
  "compilerOptions": {
    "target": "ES2022",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "moduleResolution": "bundler"
  }
}

Component Pattern

typescript
interface ButtonProps {
  children: React.ReactNode;
  onClick: () => void;
  variant?: "primary" | "secondary";
}

export function Button({ children, onClick, variant = "primary" }: ButtonProps) {
  return (
    <button onClick={onClick} className={`btn btn-${variant}`}>
      {children}
    </button>
  );
}

Server Component (Next.js)

typescript
// Server Component by default - no "use client"
export default async function PostsPage() {
  const posts = await fetch("https://api.example.com/posts").then(r => r.json());
  return <PostList posts={posts} />;
}

Client Component

typescript
"use client";

import { useState } from "react";

export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>;
}

Form with Zod Validation

typescript
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

const schema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
});

type FormData = z.infer<typeof schema>;

function LoginForm() {
  const { register, handleSubmit, formState: { errors } } = useForm<FormData>({
    resolver: zodResolver(schema),
  });
  // ...
}

React Query for API Data

typescript
import { useQuery } from "@tanstack/react-query";

export function useUsers() {
  return useQuery({
    queryKey: ["users"],
    queryFn: () => fetch("/api/users").then(r => r.json()),
    staleTime: 5 * 60 * 1000,
  });
}

CVA for Type-Safe Variants

typescript
import { cva, type VariantProps } from "class-variance-authority";

const button = cva("rounded-md font-medium", {
  variants: {
    variant: { primary: "bg-blue-600 text-white", secondary: "bg-gray-200" },
    size: { sm: "px-3 py-2 text-sm", md: "px-4 py-2", lg: "px-6 py-3" },
  },
  defaultVariants: { variant: "primary", size: "md" },
});

type ButtonProps = VariantProps<typeof button>;

Topics

TopicUse For
CoreProject setup, tsconfig, modern TS features, type utilities
ReactComponents, hooks, Context API, performance patterns
Next.jsApp Router, Server/Client Components, Server Actions, routing
TypesAdvanced types, generics, conditional types, type guards
StateZustand, React Query, Context + Reducer, URL state
FormsReact Hook Form, Zod validation, Server Actions integration
APIFetch wrappers, React Query, tRPC, GraphQL, WebSockets
TestingVitest, React Testing Library, MSW, Playwright E2E
StylingTailwind CSS, CVA variants, dark mode, responsive design
PerformanceBundle analysis, code splitting, memoization, Web Vitals
AccessibilityWCAG compliance, ARIA, keyboard navigation, screen readers
MobileReact Native, Expo, navigation, platform-specific code
ESMESM patterns, JSDoc types, JS vs TS decision guide
DebuggingConsole methods, DevTools, source maps, async debugging

Critical Rules

Always

  • Use strict mode in tsconfig
  • Type all function parameters and returns
  • Handle null/undefined explicitly
  • Use Server Components by default
  • Validate on both client and server
  • Test with screen readers
  • Measure before optimizing

Never

  • Use any (use unknown with type guards)
  • Use ! (non-null assertion) without justification
  • Store server data in client state (use React Query)
  • Rely on color alone for information
  • Create new functions in render
  • Skip error handling for API calls
  • Premature optimization