• TypeScript高级类型


    交叉类型(&)

    将多个类型合并成一个类型

    如下Test&Test1合并成类型包含nameage所以如果只返回age

    interface Test{
        name: String;
    }
    interface Test1{
        age: String;
    }
    
    function Test2(): Test & Test1{
        return {
            age:"12"
        }
       // ERROR Type '{ age: string; }' is not assignable to type 'Test & Test1'.
       // Type '{ age: string; }' is not assignable to type 'Test'.
       //  Property 'name' is missing in type '{ age: string; }'.
        // 新的类型少返回name了
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    联合类型(|)

    声明的类型并不确定,可以为多个类型中的一个

    interface Test{
        name: String;
    }
    interface Test1{
        age: String;
    }
    
    function Test2(): Test | Test1{
        return {
            age:"12"
        }
    }
    // 因为是不确定的那么,所以只返回一个age也是可以的,说明该类型是Test
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    类型别名(type)

    通过组合(交叉,联合,keyof等等操作符)作为一个新的类型并设置一个别名,这样,不需要每次都是用操作符操作一遍,万一需要改动,只需要改动type的新类型即可

    可以看到用新的P类型更完美,如果要改动,只需要改P类型即可,而不用单独再去一个一个改keyof Person

    interface Person {
      name: string;
      age: number;
      gender: string;
    }
    type P = keyof Person; //
    
    // BAD
    function IPersion():keyof Person{
        return "name"
    }
    // BAD
    function IPersion():keyof Person{
        return "age"
    }
    
    // GOOD 
    function IPersion():P{
        return "name"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    keyof

    获取类型的所有key的联合类型

    interface Person {
      name: string;
      age: number;
      gender: string;
    }
    type P = keyof Person; // 
    // 我们可以看到,keyof将Person这个对象类型映射成了一个联合类型
    等于
    type p = "name" | "age" | "gender"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Record

    接收两个泛型参数,一个keys,一个Typekeys就是这个对象的keytype就是这个key对应的类型。可以类比于a:string a属性就是keytype就是string。不过这里的type可能更复杂

    interface Person{
        name: string;
        age: number;
    }
    
    type User="user1"|"user2"
    const Users: Record<User, Person> = {
        user1: {
            age: 1,
            name:"123"
        },
        user2: {
            age: 1,
            name:"123"
        }
    }
    // 可以看到keys 就是User中的user1和user2. 而Record中的第一个泛型参数就是作为键,而第二个参数Person作为值
    
    // 所以就是新的类型就是以keys作为键,以type作为值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Partial

    将一个类型转化为键?:对应类型的方式。即转换为各个属性非必填

    Partial类型定义:

    /**
     * Make all properties in T optional
     */
    type Partial<T> = {
        [P in keyof T]?: T[P];
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以看到Partial就是将泛型T重新遍历出属性并加上?

    interface Person{
        name: string;
        age: number;
    }
    
    // Person经过 Partial会转为
    // interface Person{
    //     name?: string|undefined;
    //     age?: number|undefined;
    // }
    // ok
    const Users1: Partial<Person> = {
       name:"测试"
    }
    // ok
    const Users2: Partial<Person> = {
       
    }
    // ok
    const Users3: Partial<Person> = {
        age:1
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    Required

    Partial相反,Required会将属性变为必选的!

    interface Person{
        name?: string;
        age: number;
    }
    
    const user1: Person = {
        age:10
    }
    
    // Type '{ age: number; }' is not assignable to type 'Required'.
    //   Property 'name' is missing in type '{ age: number; }'.
    // 这里可以看到报错了,Required将name转换为必选项了
    const user2: Required<Person> = {
        age: 10
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Readonly

    Readonly同理一样是将Type转换为只读的属性

    interface Todo {
      title: string;
    }
     
    const todo: Readonly<Todo> = {
      title: "Delete inactive users",
    };
    
    //  Cannot assign to 'title' because it is a constant or a read-only property.
    // 可以看到title属性成了只读,所以会报错
    todo.title = "Hello";
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Pick

    Type(类型)中取出keys属性作为新的类型

    interface Todo {
      title: string;
      description: string;
      completed: boolean;
    }
     
    // 从Todo类型中取出title和completed组成新的类型。
    type TodoPreview = Pick<Todo, "title" | "completed">;
     
    const todo: TodoPreview = {
      title: "Clean room",
      completed: false,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Omit

    Pick相反,Pick是从类型中取出属性作为新的类型,Omit是从类型中忽略属性,之后剩下的属性组成新的类型

    interface Todo {
      title: string;
      description: string;
      completed: boolean;
      createdAt: number;
    }
     
    // TodoPreview 这个新类型没有description属性
    type TodoPreview = Omit<Todo, "description">; 
     
    const todo: TodoPreview = {
      title: "Clean room",
      completed: false,
      createdAt: 1615544252770,
    };
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Exclude

    从联合类型中去除其中一个类型,而组成新的类型

    type T0 = Exclude<"a" | "b" | "c", "a">;
    
    // Type '"a"' is not assignable to type '"b" | "c"'.
    // 这里就会报错,因为这里从联合类型中去掉了a, 那么新的T0类型其实是 type T0 = "b"|"c"
    const t1:T0 = "a"
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Extract

    Exclude相反,Extract从类型中提取Union联合类型作为新的类型。

    type T0 = Extract<"a" | "b" | "c", "a" | "f">;
    // 转换为
    type T0 = "a"
    
    • 1
    • 2
    • 3
  • 相关阅读:
    确定编写代码的规则——变量命名规则和编写规范
    丰田+比亚迪「围攻」大众,明年或将「让出」榜首之位
    java实现各种排序
    【算法-回溯法】N皇后问题
    周四见|物流人的一周资讯
    FITC荧光标记脂多糖 FITC-LPS;CY3、CY5、CY7标记芽霉菌糖/昆布多糖/海洋硫酸多糖/聚二糖/棉籽糖定制合成
    JAVA购物车实现 CarItemServiceImpl
    更新GitLab上的项目
    智云通CRM:客户说“手头紧”,如何应对才能让他下定决心购买?
    一分钟了解乐观锁、悲观锁、共享锁、排它锁、行锁、表锁以及使用场景
  • 原文地址:https://blog.csdn.net/u012733501/article/details/126022565