美文网首页
TypeScript -- 泛型

TypeScript -- 泛型

作者: _路明非_ | 来源:发表于2019-12-05 22:29 被阅读0次

    1. 很多时候我们希望一个函数或者一个类可以支持多种数据类型,有很大的灵活性
    2.泛型:不预先确定的数据类型,具体的类型在使用的时候才能确定
    3.泛型好处
    a. 函数和类可以支持多种类型,增强程序的扩展性;
    b. 不必写多条函数重载,冗余的联合类型声明,增强代码可读性;
    c. 灵活的控制了类型之间的约束;

    一 泛型函数与泛型接口

    // 一个打印函数
    function log(value: string) {
        console.log(value);
        return value;
    }
    // 希望上面的打印函数可以接收一个字符串数组
    // 函数重载
    function log(value: string): string;
    function log(value: string[]): string[];
    function log(value: any) {
        console.log(value);
        return value;
    }
    // 联合类型
    function log(value: string | string[]) {
        console.log(value);
        return value;
    }
    // 希望log可以接收任意类型
    // any类型(问题:丢失了类型之间的关系,它忽略了输入的类型和返回的类型必须是一致的)
    function log(value: any) {
        console.log(value);
        return value;
    }
    

    使用泛型改造log函数

    // 泛型函数
    // 类型T不需要预先指定,就相当于any类型
    // 可以保存输入参数和返回值类型是一致的
    function log<T>(value: T): T {
        console.log(value);
        return value;
    }
    // 两种调用方式
    log<string[]>(['1','2']);
    // 利用TS的类型推断,省略类型的参数
    //推荐这种方式
    log(['1','2']);
    
    // 利用泛型定义一个函数类型
    // type 类型别名
    type Log = <T>(value: T) => T;
    // 泛型函数的实现
    let myLog: Log = log
    
    // 泛型接口 (和类型别名的定义是完全等价的)
    // 泛型紧紧约束了一个函数,也可以约束接口的其它成员
    interface Log1 {
        <T>(value: T): T
    }
    // 这样接口的所有成员都受到了泛型的约束了
    // 当泛型约束了整个接口之后,在实现的时候必须指定一个类型
    interface Log2<T> {
        (value: T): T
    }
    // 必须指定类型,mylog2的参数只能是number
    let myLog2: Log2<number> = log
    // 设置默认值了,实现的时候就不需要必须指定一个类型了
    interface Log2<T = string> {
        (value: T): T
    }
    let myLog3: Log2 = log
    log('2')
    

    二 泛型类与泛型约束

    // 定义一个泛型类(<T>放在Log后面,约束类的所有成员)
    // 泛型不能应用于类的静态成员
    class Log<T> {
        run(value: T) {
            console.log(value);
            return value;
        }
    }
    // 实例化Log类,实例的方法将会受到泛型的约束
    let log = new Log<number>()
    log.run(1)
    // 实例化的时候也可以不传入参数,不指定参数的时候value就可以是任意值
    let log1 = new Log()
    log1.run({a:1})
    
    
    // 泛型约束,
    // 希望打印出参数和参数的属性
    interface LogLength {
        length: number;
    }
    function log3<T extends LogLength>(value: T): T {
        // 不存在length属性,需要预定义一个接口,T继承LogLength就好使了
        // 现在T就受到了一定的约束,就不是任意类型都可以传入了,输入的参数必须具有length属性
        console.log(value, value.length);
        return value;
    }
    log3([1])
    

    相关文章

      网友评论

          本文标题:TypeScript -- 泛型

          本文链接:https://www.haomeiwen.com/subject/mkijgctx.html