typescript 泛型

泛型

我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能

泛型之hello world

不使用泛型

        function indentity(arg: number): number {
    return arg
        }

        function identity(arg: any): any {
    return arg;
        }

使用any类型会导致这个函数可以接收任何类型的arg参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的。如果我们传入一个数字,我们只知道任何任性的值都有可能被返回

因此,我们需要一种方法使返回值的类型与传入的参数的类型时相同的。
这里我们使用了类型变量,它是一种特殊的变量,只用于表示类型而不是值

    // 类型变量T,
    function indentity<T>(arg:T):T{
        return arg
    }

T帮助我们捕获用户传入的类型,之后我们就可以使用这个类型。
现在我们可以知道参数类型与返回值类型时相同的了。这允许我们跟踪函数里使用的类型的信息

    let output = identity<string>('sss')
    let output = identity<number>(1)

使用泛型变量

如果你需要在函数内部使用参数的length属性,可以这样使用

    // 会报错,因为T可能是number,number没有length属性
    function loggingIdentity<T>(arg: T): T {
        console.log(arg.length);  // Error: T doesn't have .length
        return arg;
    }
    function loggingIdentity<T>(arg: T[]): T[] {
        console.log(arg.length);  // Array has a .length, so no more error
        return arg;
    }
    // 或者
    function loggingIdentity<T>(arg: Array<T>): Array<T> {
        console.log(arg.length);  // Array has a .length, so no more error
        return arg;
    }

泛型类型

  1. 泛型函数的类型与非泛型函数的类型没有什么不同,只是有一个类型参数在最前面
    function identity<T>(arg: T):T {
        return arg
    }

    let myIdentity: <T>(arg: T) => T = inentity
    // 或
    let myIdentity: {<T>(arg: T) => T} = inentity
    myIdentity(10) // 10
  1. 泛型接口
    interface IIdentityFn{
        <T>(arg:T):T
    }
    function identity<T>(arg:T):T {
        return arh
    }

    let myIdentity: IIdentityFn = identity

  1. 把泛型的参数当做接口的参数
     interface IIdentityFn<T> {
         (arg:T):T
     }
     function identity<T>(arg: T): T {
         return arg;
     }
    
     let myIdentity: IIdentityFn<number> = identity
    

注意:以上示例,不在描述泛型函数,而是把非泛型函数签名作为泛型类型的一部分。当我们使用IIdentityFn的时候,还得传入一个类型参数来执行反省了类型(这里是number),锁定了之后代码里使用的类型。

泛型类

泛型类看上去与泛型接口差不多。 泛型类使用(<>)括起泛型类型,跟在类名后面

    class Gener<T> {
        zero: T
        add: (x: T, y:T) => T // T类型的x,y参数 返回T类型的值
    }

    let myGen = new Gen<number>()
    myGen.zero = 0
    myGen.add = function(x,y) {
        return x+y
    }

泛型约束

    interface LenWise {
        length: number
    }

    function loggingIden<T extends LenWise>(arg: T) {
        console.log(arg.length)
        return arg
    }

在泛型约束中使用类型参数

你可以声明一个类型参数,且她被另一个类型参数所约束。比如,
    function getProperty(obj: T, key: K) {
        return obj[key]
    }

    let x = {a:1, b:2, c:3}
    getProperty(x, 'a')
    getProperty(x, 'm')
上一篇:11亿条数据压缩到12GB,TDengine在陕煤矿山项目的落地实践


下一篇:TypeScript 类型系统