侧边栏壁纸
博主头像
DevWiki博主等级

不怕慢,只怕站!

  • 累计撰写 161 篇文章
  • 累计创建 94 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

TypeScript 中的实用类型(utility type)和转换类型

DevWiki
2024-06-12 / 0 评论 / 0 点赞 / 27 阅读 / 8828 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2024-06-12,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

在学习 TypeScript 中遇到了Record 这个类型, 一开始不知道其用途, 查找了一下说明才得知:

Record<K extends keyof any, T> 是 TypeScript 提供的一个实用类型(utility type),用于构造一个对象类型,其中键 K 的集合可以是任意类型(通常是字符串、数字或符号),对应的值类型为 T

1. 详细解释

1.1 定义

Record<K extends keyof any, T> 的定义如下:

type Record<K extends keyof any, T> = {
    [P in K]: T;
};
  • K extends keyof any:表示 K 可以是任何合法的键类型。keyof any 是 TypeScript 中的一个特殊类型,它等价于 string | number | symbol
  • T:表示属性的值的类型。
  • { [P in K]: T; }:这是一种映射类型语法,表示生成一个对象类型,这个对象的键是 K 中的每一个键,其对应的值类型都是 T

1.2 用法示例

  1. 创建一个简单的对象类型
    假设我们想要创建一个对象类型,键是字符串,值是数字:

    type StringToNumberMap = Record<string, number>;
    
    const example: StringToNumberMap = {
        a: 1,
        b: 2,
        c: 3
    };
    
  2. 限制键的集合
    假设我们有一组特定的键,值的类型是布尔型:

    type Options = "option1" | "option2" | "option3";
    type OptionFlags = Record<Options, boolean>;
    
    const example: OptionFlags = {
        option1: true,
        option2: false,
        option3: true
    };
    
  3. 结合接口使用
    如果我们有一个接口 Person,我们想要创建一个包含多个 Person 对象的记录:

    interface Person {
        name: string;
        age: number;
    }
    
    type PersonDictionary = Record<string, Person>;
    
    const persons: PersonDictionary = {
        john: { name: "John Doe", age: 25 },
        jane: { name: "Jane Smith", age: 30 }
    };
    

1.3 详细示例

假设我们需要管理一组用户,每个用户都有一个唯一的标识符(ID)。我们可以使用 Record 来定义一个用户字典:

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

type UserDictionary = Record<number, User>;

const users: UserDictionary = {
    1: { id: 1, name: "John Doe", email: "john.doe@example.com" },
    2: { id: 2, name: "Jane Smith", email: "jane.smith@example.com" },
    3: { id: 3, name: "Emily Johnson", email: "emily.johnson@example.com" }
};

// 访问用户信息
console.log(users[1].name);  // 输出: John Doe

在这个示例中:

  • User 接口定义了用户对象的结构。
  • UserDictionary 使用 Record<number, User> 创建了一个类型,该类型的键是数字,值是 User 类型。
  • users 变量是一个 UserDictionary 类型的对象,包含多个用户条目。

2. 类型工具

Record<K extends keyof any, T> 类型在 TypeScript 中非常有用,可以用来定义一个键和值类型的映射。它允许我们动态地创建具有特定键集合和值类型的对象类型,广泛应用于需要键值对数据结构的场景。

在 TypeScript 中还有不少类似的类型工具用于操作和转换类型。以下是它们的具体区别和用途:

  1. Partial

    • 作用:将类型 T 的所有属性变为可选。
    • 用法
      interface Person {
          name: string;
          age: number;
      }
      type PartialPerson = Partial<Person>;
      // Equivalent to: { name?: string; age?: number; }
      
  2. Required

    • 作用:将类型 T 的所有属性变为必需。
    • 用法
      interface Person {
          name?: string;
          age?: number;
      }
      type RequiredPerson = Required<Person>;
      // Equivalent to: { name: string; age: number; }
      
  3. Readonly

    • 作用:将类型 T 的所有属性变为只读。
    • 用法
      interface Person {
          name: string;
          age: number;
      }
      type ReadonlyPerson = Readonly<Person>;
      // Equivalent to: { readonly name: string; readonly age: number; }
      
  4. Pick<T, K extends keyof T>

    • 作用:从类型 T 中挑选一组属性 K 组成新的类型。
    • 用法
      interface Person {
          name: string;
          age: number;
          address: string;
      }
      type PersonNameAndAge = Pick<Person, 'name' | 'age'>;
      // Equivalent to: { name: string; age: number; }
      
  5. Record<K extends keyof any, T>

    • 作用:构建一个类型,其键为 K 类型,值为 T 类型。
    • 用法
      type PersonRecord = Record<string, number>;
      // Equivalent to: { [key: string]: number; }
      
  6. Exclude<T, U>

    • 作用:从类型 T 中排除可以赋值给 U 的类型。
    • 用法
      type T = string | number | boolean;
      type Excluded = Exclude<T, boolean>;
      // Equivalent to: string | number
      
  7. Extract<T, U>

    • 作用:从类型 T 中提取可以赋值给 U 的类型。
    • 用法
      type T = string | number | boolean;
      type Extracted = Extract<T, boolean>;
      // Equivalent to: boolean
      
  8. Omit<T, K extends keyof any>

    • 作用:构建一个类型,其具有类型 T 的属性,除了那些在 K 中的属性。
    • 用法
      interface Person {
          name: string;
          age: number;
          address: string;
      }
      type PersonWithoutAddress = Omit<Person, 'address'>;
      // Equivalent to: { name: string; age: number; }
      
  9. NonNullable

    • 作用:从类型 T 中排除 nullundefined
    • 用法
      type T = string | number | null | undefined;
      type NonNullableT = NonNullable<T>;
      // Equivalent to: string | number
      
  10. Parameters<T extends (...args: any) => any>

    • 作用:获取函数类型 T 的参数类型组成的元组。
    • 用法
      type Func = (a: string, b: number) => void;
      type Params = Parameters<Func>;
      // Equivalent to: [string, number]
      

这些类型工具在类型操作和变换中非常有用,帮助开发者更灵活地处理和定义类型。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区