mcpField
T
typescript-advanced-types

typescript-advanced-types

github.com/midudev开发7.0k64 次安装今天更新
代码仓库

关于 typescript-advanced-types

面向构建类型安全 TypeScript 应用的开发者,讲解泛型、条件类型、映射类型、模板字面量类型和工具类型。还涵盖类型测试、实践建议与常见陷阱。

主要功能

  1. 01泛型与约束
  2. 02条件类型和类型推断
  3. 03映射类型与键重映射
  4. 04模板字面量类型
  5. 05工具类型与类型测试

适用场景

  1. 01构建类型安全的库或框架
  2. 02设计可复用泛型组件
  3. 03实现类型安全的 API 客户端
  4. 04将 JavaScript 项目迁移到 TypeScript

安装

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

$npx skills add https://github.com/midudev/autoskills --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