mcpField
T
typescript-advanced-types

typescript-advanced-types

github.com/wshobson开发41.9k94.3k 次安装2 周前更新
代码仓库

关于 typescript-advanced-types

typescript-advanced-types 是面向开发者的 TypeScript 高级类型参考 Skill,涵盖可复用的类型模式和实用示例,也涉及类型测试与常见陷阱。

主要功能

  1. 01泛型与约束
  2. 02条件类型和映射类型
  3. 03模板字面量类型
  4. 04内置工具类型
  5. 05类型测试与最佳实践

适用场景

  1. 01设计类型安全的 API 客户端
  2. 02构建可复用的泛型组件
  3. 03创建类型化表单验证
  4. 04将 JavaScript 迁移到 TypeScript

安装

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

$npx skills add https://github.com/wshobson/agents --skill typescript-advanced-types

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

附带文件references/details.md

详细介绍

TypeScript 高级类型

全面指导你掌握 TypeScript 的高级类型系统,包括泛型、条件类型、映射类型、模板字面量类型和工具类型,帮助你构建健壮且类型安全的应用程序。

何时使用本技能

  • 构建类型安全的库或框架
  • 创建可复用的泛型组件
  • 实现复杂的类型推断逻辑
  • 设计类型安全的 API 客户端
  • 构建表单验证系统
  • 创建强类型的配置对象
  • 实现类型安全的状态管理
  • 将 JavaScript 代码库迁移到 TypeScript

核心概念

1. 泛型

目的: 在保持类型安全的同时,创建可复用且类型灵活的组件。

基础泛型函数:

function identity<T>(value: T): T {
  return value;
}

const num = identity<number>(42); // Type: number
const str = identity<string>("hello"); // Type: string
const auto = identity(true); // Type inferred: boolean

泛型约束:

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({ length: 10 }); // OK: object has length
// logLength(42);             // Error: number has no length

多个类型参数:

function merge<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

const merged = merge({ name: "John" }, { age: 30 });
// Type: { name: string } & { age: number }
2. 条件类型

目的: 创建依赖于条件的类型,实现复杂的类型逻辑。

基础条件类型:

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

type A = IsString<string>; // true
type B = IsString<number>; // false

提取返回类型:

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUser() {
  return { id: 1, name: "John" };
}

type User = ReturnType<typeof getUser>;
// Type: { id: number; name: string; }

分布式条件类型:

type ToArray<T> = T extends any ? T[] : never;

type StrOrNumArray = ToArray<string | number>;
// Type: string[] | number[]

嵌套条件:

type TypeName<T> = T extends string
  ? "string"
  : T extends number
    ? "number"
    : T extends boolean
      ? "boolean"
      : T extends undefined
        ? "undefined"
        : T extends Function
          ? "function"
          : "object";

type T1 = TypeName<string>; // "string"
type T2 = TypeName<() => void>; // "function"
3. 映射类型

目的: 通过遍历现有类型的属性来转换它们。

基础映射类型:

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

interface User {
  id: number;
  name: string;
}

type ReadonlyUser = Readonly<User>;
// Type: { readonly id: number; readonly name: string; }

可选属性:

type Partial<T> = {
  [P in keyof T]?: T[P];
};

type PartialUser = Partial<User>;
// Type: { id?: number; name?: string; }

键重映射:

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface Person {
  name: string;
  age: number;
}

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

过滤属性:

type PickByType<T, U> = {
  [K in keyof T as T[K] extends U ? K : never]: T[K];
};

interface Mixed {
  id: number;
  name: string;
  age: number;
  active: boolean;
}

type OnlyNumbers = PickByType<Mixed, number>;
// Type: { id: number; age: number; }
4. 模板字面量类型

目的: 创建基于字符串、支持模式匹配和转换的类型。

基础模板字面量:

type EventName = "click" | "focus" | "blur";
type EventHandler = `on${Capitalize<EventName>}`;
// Type: "onClick" | "onFocus" | "onBlur"

字符串操作:

type UppercaseGreeting = Uppercase<"hello">; // "HELLO"
type LowercaseGreeting = Lowercase<"HELLO">; // "hello"
type CapitalizedName = Capitalize<"john">; // "John"
type UncapitalizedName = Uncapitalize<"John">; // "john"

路径构建:

type Path<T> = T extends object
  ? {
      [K in keyof T]: K extends string ? `${K}` | `${K}.${Path<T[K]>}` : never;
    }[keyof T]
  : never;

interface Config {
  server: {
    host: string;
    port: number;
  };
  database: {
    url: string;
  };
}

type ConfigPath = Path<Config>;
// Type: "server" | "database" | "server.host" | "server.port" | "database.url"
5. 工具类型

内置工具类型:

// Partial<T> - Make all properties optional
type PartialUser = Partial<User>;

// Required<T> - Make all properties required
type RequiredUser = Required<PartialUser>;

// Readonly<T> - Make all properties readonly
type ReadonlyUser = Readonly<User>;

// Pick<T, K> - Select specific properties
type UserName = Pick<User, "name" | "email">;

// Omit<T, K> - Remove specific properties
type UserWithoutPassword = Omit<User, "password">;

// Exclude<T, U> - Exclude types from union
type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"

// Extract<T, U> - Extract types from union
type T2 = Extract<"a" | "b" | "c", "a" | "b">; // "a" | "b"

// NonNullable<T> - Exclude null and undefined
type T3 = NonNullable<string | null | undefined>; // string

// Record<K, T> - Create object type with keys K and values T
type PageInfo = Record<"home" | "about", { title: string }>;

详细示例与模式

详细章节(以 ## Advanced Patterns 开头)位于 references/details.md。当上述导航摘要不够充分时,请阅读该文件。

最佳实践

  1. 使用 unknown 而不是 any:强制进行类型检查
  2. 对象形状优先使用 interface:错误信息更清晰
  3. 联合类型和复杂类型使用 type:更灵活
  4. 充分利用类型推断:尽可能让 TypeScript 自行推断
  5. 创建辅助类型:构建可复用的类型工具
  6. 使用 const 断言:保留字面量类型
  7. 避免类型断言:改用类型守卫
  8. 为复杂类型编写文档:添加 JSDoc 注释
  9. 使用严格模式:启用所有严格编译器选项
  10. 测试你的类型:使用类型测试验证类型行为

类型测试

// Type assertion tests
type AssertEqual<T, U> = [T] extends [U]
  ? [U] extends [T]
    ? true
    : false
  : false;

type Test1 = AssertEqual<string, string>; // true
type Test2 = AssertEqual<string, number>; // false
type Test3 = AssertEqual<string | number, string>; // false

// Expect error helper
type ExpectError<T extends never> = T;

// Example usage
type ShouldError = ExpectError<AssertEqual<string, number>>;

常见陷阱

  1. 过度使用 any:违背了 TypeScript 的初衷
  2. 忽略严格空值检查:可能导致运行时错误
  3. 类型过于复杂:可能拖慢编译速度
  4. 不使用可辨识联合:错失类型收窄的机会
  5. 忘记 readonly 修饰符:允许了意外的修改
  6. 循环类型引用:可能导致编译器错误
  7. 不处理边界情况:例如空数组或空值

性能考量

  • 避免深层嵌套的条件类型
  • 尽可能使用简单类型
  • 缓存复杂的类型计算
  • 限制递归类型的递归深度
  • 在生产环境中使用构建工具跳过类型检查

评论

支持 Markdown