mcpField
M
mastering-typescript

mastering-typescript

github.com/spillwavesolutions开发31795 次安装43 周前更新
代码仓库

关于 mastering-typescript

mastering-typescript 面向构建或迁移 TypeScript 应用的开发者,汇集现代类型系统模式、框架示例、Zod 验证和工具链配置,并提供参考指南与配置资源。

主要功能

  1. 01现代 TypeScript 类型系统模式
  2. 02泛型、映射类型与条件类型
  3. 03React 和 NestJS 示例
  4. 04Zod 模式验证
  5. 05工具链配置指南
  6. 06迁移指南与配置资源

适用场景

  1. 01构建类型安全的 React 或 NestJS 应用
  2. 02逐步迁移 JavaScript 代码库
  3. 03使用 Zod 设计经过验证的 API 契约
  4. 04配置 TypeScript 项目工具

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/spillwavesolutions/mastering-typescript-skill --skill mastering-typescript

安装后在 Claude Code 中输入/mastering-typescript确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

assets/
eslint-template.js
tsconfig-template.json
references/
enterprise-patterns.md
generics.md
nestjs-integration.md
react-integration.md
toolchain.md
type-system.md
scripts/
validate-setup.sh

详细介绍

掌握现代 TypeScript

使用 TypeScript 5.9+ 构建企业级、类型安全的应用程序。

兼容性: TypeScript 5.9+、Node.js 22 LTS、Vite 7、NestJS 11、React 19

快速开始

# Initialize TypeScript project with ESM
pnpm create vite@latest my-app --template vanilla-ts
cd my-app && pnpm install

# Configure strict TypeScript
cat > tsconfig.json << 'EOF'
{
  "compilerOptions": {
    "target": "ES2024",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}
EOF

何时使用此技能

适用于:

  • 构建类型安全的 React、NestJS 或 Node.js 应用程序
  • 将 JavaScript 代码库迁移到 TypeScript
  • 实现高级类型模式(泛型、映射类型、条件类型)
  • 配置现代 TypeScript 工具链(Vite、pnpm、ESLint)
  • 使用 Zod 验证设计类型安全的 API 契约
  • 将 TypeScript 方案与 Java 或 Python 方案进行比较

项目设置清单

开始任何 TypeScript 项目之前:

- [ ] Use pnpm for package management (faster, disk-efficient)
- [ ] Configure ESM-first (type: "module" in package.json)
- [ ] Enable strict mode in tsconfig.json
- [ ] Set up ESLint with @typescript-eslint
- [ ] Add Prettier for consistent formatting
- [ ] Configure Vitest for testing

类型系统速查

基本类型
const name: string = "Alice";
const age: number = 30;
const active: boolean = true;
const id: bigint = 9007199254740991n;
const key: symbol = Symbol("unique");
联合类型和交叉类型
// Union: value can be one of several types
type Status = "pending" | "approved" | "rejected";

// Intersection: value must satisfy all types
type Employee = Person & { employeeId: string };

// Discriminated union for type-safe handling
type Result<T> =
  | { success: true; data: T }
  | { success: false; error: string };

function handleResult<T>(result: Result<T>): T | null {
  if (result.success) {
    return result.data; // TypeScript knows data exists here
  }
  console.error(result.error);
  return null;
}
类型守卫
// typeof guard
function process(value: string | number): string {
  if (typeof value === "string") {
    return value.toUpperCase();
  }
  return value.toFixed(2);
}

// Custom type guard
interface User { type: "user"; name: string }
interface Admin { type: "admin"; permissions: string[] }

function isAdmin(person: User | Admin): person is Admin {
  return person.type === "admin";
}
satisfies 运算符(TS 5.0+)

在验证类型兼容性的同时保留类型推断:

// Problem: Type assertion loses specific type info
const colors1 = {
  red: "#ff0000",
  green: "#00ff00"
} as Record<string, string>;

colors1.red.toUpperCase(); // OK, but red could be undefined

// Solution: satisfies preserves literal types
const colors2 = {
  red: "#ff0000",
  green: "#00ff00"
} satisfies Record<string, string>;

colors2.red.toUpperCase(); // OK, and TypeScript knows red exists

泛型模式

基本泛型函数
function first<T>(items: T[]): T | undefined {
  return items[0];
}

const num = first([1, 2, 3]);     // number | undefined
const str = first(["a", "b"]);   // string | undefined
受约束的泛型
interface HasLength {
  length: number;
}

function logLength<T extends HasLength>(item: T): T {
  console.log(item.length);
  return item;
}

logLength("hello");     // OK: string has length
logLength([1, 2, 3]);   // OK: array has length
logLength(42);          // Error: number has no length
泛型 API 响应包装器
interface ApiResponse<T> {
  data: T;
  status: number;
  timestamp: Date;
}

async function fetchUser(id: string): Promise<ApiResponse<User>> {
  const response = await fetch(`/api/users/${id}`);
  const data = await response.json();
  return {
    data,
    status: response.status,
    timestamp: new Date()
  };
}

工具类型参考

类型用途示例
Partial<T>所有属性均为可选Partial<User>
Required<T>所有属性均为必需Required<Config>
Pick<T, K>选取特定属性Pick<User, "id" | "name">
Omit<T, K>排除特定属性Omit<User, "password">
Record<K, V>键和值均有类型的对象Record<string, number>
ReturnType<F>提取函数返回类型ReturnType<typeof fn>
Parameters<F>提取函数参数Parameters<typeof fn>
Awaited<T>解包 Promise 类型Awaited<Promise<User>>

条件类型

// Basic conditional type
type IsString<T> = T extends string ? true : false;

// Extract array element type
type ArrayElement<T> = T extends (infer E)[] ? E : never;

type Numbers = ArrayElement<number[]>; // number
type Strings = ArrayElement<string[]>; // string

// Practical: Extract Promise result type
type UnwrapPromise<T> = T extends Promise<infer R> ? R : T;

映射类型

// Make all properties readonly
type Immutable<T> = {
  readonly [K in keyof T]: T[K];
};

// Make all properties nullable
type Nullable<T> = {
  [K in keyof T]: T[K] | null;
};

// Create getter functions for each property
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface Person { name: string; age: number }
type PersonGetters = Getters<Person>;
// { getName: () => string; getAge: () => number }

框架集成

使用 TypeScript 的 React
// Typed functional component
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary";
}

const Button: React.FC<ButtonProps> = ({ label, onClick, variant = "primary" }) => (
  <button className={variant} onClick={onClick}>
    {label}
  </button>
);

// Typed hooks
const [count, setCount] = useState<number>(0);
const userRef = useRef<HTMLInputElement>(null);
使用 TypeScript 的 NestJS
// Type-safe DTO with class-validator
import { IsString, IsEmail, MinLength } from 'class-validator';

class CreateUserDto {
  @IsString()
  @MinLength(2)
  name: string;

  @IsEmail()
  email: string;
}

// Or with Zod (modern approach)
import { z } from 'zod';

const CreateUserSchema = z.object({
  name: z.string().min(2),
  email: z.string().email()
});

type CreateUserDto = z.infer<typeof CreateUserSchema>;

详细模式请参阅 react-integration.md 和 nestjs-integration.md。

使用 Zod 进行验证

import { z } from 'zod';

// Define schema
const UserSchema = z.object({
  id: z.string().uuid(),
  name: z.string().min(1).max(100),
  email: z.string().email(),
  role: z.enum(["user", "admin", "moderator"]),
  createdAt: z.coerce.date()
});

// Infer TypeScript type from schema
type User = z.infer<typeof UserSchema>;

// Validate at runtime
function parseUser(data: unknown): User {
  return UserSchema.parse(data); // Throws ZodError if invalid
}

// Safe parsing (returns result object)
const result = UserSchema.safeParse(data);
if (result.success) {
  console.log(result.data); // Typed as User
} else {
  console.error(result.error.issues);
}

现代工具链(2025)

工具版本用途
TypeScript5.9+类型检查和编译
Node.js22 LTS运行时环境
Vite7.x构建工具和开发服务器
pnpm9.x包管理器
ESLint9.x使用扁平配置进行代码检查
Vitest3.x测试框架
Prettier3.x代码格式化
ESLint 扁平配置(ESLint 9+)
// eslint.config.js
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  }
);

迁移策略

渐进式迁移
  1. 在 tsconfig.json 中添加 allowJs: true 和 checkJs: false
  2. 一次将一个文件从 .js 重命名为 .ts
  3. 逐步添加类型注解
  4. 逐步启用更严格的选项
使用 JSDoc 逐步添加类型
// Before full migration, use JSDoc
/**
 * @param {string} name
 * @param {number} age
 * @returns {User}
 */
function createUser(name, age) {
  return { name, age };
}

全面的迁移指南请参阅 enterprise-patterns.md。

常见错误

错误问题修正方法
滥用 any破坏类型安全使用 unknown 并缩小类型范围
忽略严格模式遗漏 null/undefined 错误启用所有严格选项
类型断言(as)可能掩盖类型错误使用 satisfies 或类型守卫
为简单联合类型使用枚举会生成运行时代码改用字面量联合类型
不验证 API 数据运行时类型不匹配在边界处使用 Zod

跨语言比较

特性TypeScriptJavaPython
类型系统结构化名义化渐进式(鸭子类型)
可空性显式(T | null)@Nullable 注解通过 typing 实现可选类型
泛型类型级,已擦除类型级,已擦除通过 typing 在运行时实现
接口结构匹配必须实现Protocol(3.8+)
枚举避免使用(改用联合类型)一等类型Enum 类

参考文件

资源文件

脚本

评论

支持 Markdown