• 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
  • 相关阅读:
    Vue学习笔记(二)
    自媒体新人,如何快速积累粉丝,我的业余Python能帮助我干些什么
    Qt创建线程(继承于QThread的方法)
    计算机专业毕业论文java毕业设计网站SSM教学管理系统[包运行成功]
    使用docker搭建DVWA
    编程语言学习杂谈
    辅助驾驶功能开发-功能规范篇(22)-3-L2级辅助驾驶方案功能规范
    JSTL标签库
    【Flink】第一节 源码编译
    专利文献的参考文献格式是什么?
  • 原文地址:https://blog.csdn.net/u012733501/article/details/126022565