Mercer-Lee的空间

vuePress-theme-reco Mercer-Lee的空间    2018 - 2024
Mercer-Lee的空间 Mercer-Lee的空间

Choose mode

  • dark
  • auto
  • light
TimeLine
分类
  • 数据结构和算法
  • 后端
  • 运维
  • 前端
  • 工具
  • 语言
标签
我的GitHub (opens new window)
author-avatar

Mercer-Lee的空间

27

文章

29

标签

TimeLine
分类
  • 数据结构和算法
  • 后端
  • 运维
  • 前端
  • 工具
  • 语言
标签
我的GitHub (opens new window)
  • 详解Typescript常用的高级类型

    • 前置知识:keyof
      • 前置知识:Mapped types
        • Record类型
          • Partial类型
            • Readonly类型
              • Pick类型
                • 总结

                详解Typescript常用的高级类型

                vuePress-theme-reco Mercer-Lee的空间    2018 - 2024

                详解Typescript常用的高级类型


                Mercer-Lee的空间 2020-06-29 TS JS

                TS中有官方给出的高级类型来辅助我们日常开发,但是无论是书本还是文档讲的都不是很清晰,网上的文章更是生涩难懂,故写下这篇文章来记录和帮助需要的人。

                # 前置知识:keyof

                首先在了解高级类型之前要先理解keyof:

                interface User {
                  name: string;
                  mobile: string;
                }
                
                type keys = keyof User; // 相当于type keys = 'name' | 'mobile'
                

                从上面可以看出,keyof是取interface的键。理解了keyof才能理解后面的高级类型:Record、Pick。

                # 前置知识:Mapped types

                Mapped types是Typescript的映射类型,能够让你快速创建类型:

                type NewUser = {
                  [K in 'name' | 'mobile']: string;
                };
                
                // 上面的代码等同于:
                type NewUser = {
                  name: string;
                  mobile: string;
                }
                

                根据上面的keyof我们也可以:

                interface User {
                  name: string;
                  mobile: string;
                }
                
                type NewUser = {
                  [K in keyof User]: string;
                };
                

                前置知识已经学完了,后面我们可以进入主题学习Typescript的高级类型了。

                # Record类型

                Record类型是最常用的类型,可以快速创建一个类型,我们先来看Record的源码:

                /**
                 * Construct a type with a set of properties K of type T
                 */
                type Record<K extends keyof any, T> = {
                    [P in K]: T;
                };
                

                看代码其实已经很明显了,结合上面的前置知识的代码,我们可以直接示例:

                
                type User = Record<'name' | 'mobile', string>;
                
                // 上面的代码相当于
                type User = {
                  name: string;
                  mobile: string;
                }
                

                # Partial类型

                Partial类型是将类型的所有属性都修改为可选。源码如下:

                /**
                 * Make all properties in T optional
                 */
                type Partial<T> = {
                    [P in keyof T]?: T[P];
                };
                

                Partial的使用如下:

                type User = {
                  name: string;
                  mobile: string;
                }
                
                type NewUser = Partial<User>;
                
                // 相当于
                type NewUser = {
                  name?: string;
                  mobile?: string;
                }
                

                结合Record我们也可以这样:

                type NewUser = Partial<Record<'name' | 'mobile', string>>;
                

                # Readonly类型

                Readonly类型就跟名字一样,将传入的类型的所有属性都定义为只读。源码如下:

                /**
                 * Make all properties in T readonly
                 */
                type Readonly<T> = {
                  readonly [P in keyof T]: T[P];
                };
                

                具体使用如下:

                type User = Readonly<Record<'name' | 'mobile', string>>;
                
                // 等同于
                type User = {
                  readonly name: string;
                  readonly mobile: string;
                }
                

                # Pick类型

                Pick类型是将传入的类型,选择一个指定的类型然后返回一个新的类型。源码如下:

                /**
                 * From T, pick a set of properties whose keys are in the union K
                 */
                type Pick<T, K extends keyof T> = {
                    [P in K]: T[P];
                };
                

                具体使用如下:

                type User = {
                  name: string;
                  mobile: string;
                  address: string;
                }
                
                type NewUser = Pick<User, 'name' | 'mobile'>;
                
                // 相当于
                type NewUser = {
                  name: string;
                  mobile: string;
                }
                

                # 总结

                其实这些高级类型Typescript在2016年就给出了,所以早就被应用在了一些包和框架上,这些类型其实在日常的开发中也是能够用到的,故记录下来。