把TS内置类型说完吧,通俗易懂(一期)

写一下TS的内置类型的用法吧,看网上资料太多太杂了不全,内容均来自官网

Partial

官网解释:构造一个类型,该类型的所有属性都设置为可选。此实用程序将返回一个表示给定类型的所有子集的类型。

namespace TPartial {
  type T0= {
    name: string;
    age: number;
    gender: string;
  };
  // 将我们传入的MangSeng类型遍历以后置为可选类型
  const useData: Partial<T0> = {
    /**
     * name?: string
     * age?: number
     */
  };

  // 源码
  // type Partial<T> = {
  //     [P in keyof T]?: T[P];
  // };
  /**
   * 1. keyof 遍历T0为联合类型 name: string | age: number
   * 2. in 取出遍历后的key,P相当与 name | age
   * 3. 结果: name?: T0[name] = string  age?: T0[age] = number
   */
  type MyPartial<T0> = {
    [P in keyof T0]?: T0[P];
  };
}

Required

namespace IRequired {
  type MangSengRequired = {
    name?: string;
    age?: number;
  };
  // 将传入的MangSengRequired类型遍历以后置为必填类型
  // const requiredUseData: Required<MangSengRequired> = {
  //   name: "回旋踢",
  // }; // 类型 "{ name: string; }" 中缺少属性 "age",但类型 "Required<MangSengRequired>" 中需要该属性
  // const requiredUseData2: Required<MangSengRequired> = {
  //   name: "回旋踢",
  //   age: 20,
  // };
  //源码
  // type Required<T> = {
  //   [P in keyof T]-?: T[P];
  // };
  // 1. -? 作用是将T中所有的属性都变成必须的属性
}

Readonly

namespace TReadonly {
  type MangSengReadonly = {
    name: string;
    age: number;
  };

  const readonlyUseData: Readonly<MangSengReadonly> = {
    name: "回旋踢",
    age: 14,
  };

  // readonlyUseData.age = 20; // 无法为“age”赋值,因为它是只读属性

  // 源码 遍历T 添加 readonly关键字
  // type Readonly<T> = {
  //     readonly [P in keyof T]: T[P];
  // };
}

Record

// 官网解释:构造属性键为keys、属性值为type的对象类型。此实用程序可用于将一个类型的属性映射到另一个类型。

namespace TRecord {
  interface CatInfo {
    age: number;
    breed: string;
  }
  type CatName = "miffy" | "boris" | "mordred";
  // 1. 使用这个类型: Record<CatName, CatInfo>
  // 2. key必须为CatName中的值, value必须实现CatInfo类型
  const data: Record<CatName, CatInfo> = {
    miffy: {
      age: 20,
      breed: "hei",
    },
    boris: {
      age: 21,
      breed: "hei",
    },
    mordred: {
      age: 22,
      breed: "hei",
    },
  };

  // 源码
  // 1. 接收两个类型
  // 2. keyof any 取值为 string | number | symbol,CatName只能是这三种类型
  // 3. CatInfo: T
  // type Record<K extends keyof any, T> = {
  //     [P in K]: T;
  // };
}

Pick<Type, Keys>

官网解释:通过从type中拾取属性集Keys(字符串文字或字符串文字的并集)来构造类型

namespace TPick {
  interface Todo {
    title: string;
    description: string;
    completed: boolean;
  }
  // 类似于类型收缩,从Todo中取出"title" | "completed"
  type TodoPreview = Pick<Todo, "title" | "completed">;

  const todo: TodoPreview = {
    title: "123123",
    completed: false,
    // 不能将类型“{ title: string; completed: false; description: string; }”分配给类型“TodoPreview”。
    // 对象字面量只能指定已知属性,并且“description”不在类型“TodoPreview”中。
    //   description:"123123"
  };
  // 源码
  // 1. K 继承于遍历后的T 也就是  title: string | completed: boolean;联合类型
  // 2.  [P in K]: T[P]; ==> [title in K]: Todo[title]
  // type Pick<T, K extends keyof T> = {
  //     [P in K]: T[P];
  // };
}

Omit<Type, Keys>

官网解释:通过从type中拾取所有属性,然后移除Keys(字符串文字或字符串文字的并集)来构造类型。与Pick相反。

namespace IOmit {
  interface Todo {
    title?: string;
    description: string;
    completed: boolean;
    createdAt: number;
  }
  /**
   * @description 在Todo类型中排除description字段
   * @description TodoPreview类型中没有了description字段
   * @description Omit与Pick相反
   */
  type TodoPreview = Omit<Todo, "description">;
  // 源码
  // type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
}

Exclude<UnionType, ExcludedMembers>

官网解释:通过从UnionType中排除可分配给ExcludedMembers的所有联合成员来构造类型。

namespace IExclude {
  type T0 = Exclude<"a" | "b" | "c", "a">;
  //   type Shape =
  //     | { kind: "circle"; radius: number }
  //     | { kind: "square"; x: number }
  //     | { kind: "triangle"; x: number; y: number };

  type Shape = "circle" | "square" | "triangle";
  /**
   * @description 在Shape类型中排除掉circle类型,T3的类型为 "square" | "triangle";
   * @description 如果Shape为对象类型,只要T包含了K那么就将K排除掉
   */
  type T3 = Exclude<Shape, "circle">;
  /**
   * @description 源码
   * @description T包含了U则返回never否则返回T
   */
  type Exclude<T, U> = T extends U ? never : T;
}

Extract<Type, Union>

官网解释:通过从类型中提取可分配给并集的所有并集成员来构造类型。

namespace IExtract {
  // 根据类型取出对应的类型
  // 从 "a" | "b" | "c" 取出 'b'
  // T0: 'b'
  type T0 = Extract<"a" | "b" | "c", "b">;
  // T1: () => void
  type T1 = Extract<number | (() => void) | boolean, Function>;
  const achieve: T1 = () => {};
  type Shape =
    | { kind: "circle"; radius: number }
    | { kind: "square"; x: number }
    | { kind: "triangle"; x: number; y: number };
  // T2:  { kind: "circle"; radius: number }
  type T2 = Extract<Shape, { kind: "circle" }>;
  // 源码实现
  type MyExtract<T, K> = T extends K ? T : never;
  type MT0 = MyExtract<number | string, string>;
}

下一期会把所有的内置内类型补充完整,这些是我在开发中常用的内置类型

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值