学习TypeScript14---泛型

47 阅读2分钟

泛型在TypeScript是很重要的东西 例如Vue3使用ts编写的 里面用到了非常多的泛型

函数泛型

两个函数一个是数字类型的函数,另一个是字符串类型的函数,其实就是类型不同,实现的功能是一样的,这时候我们就可以使用泛型来优化

function num(a: number, b: number): Array<number> {
    return [a, b]
}
num(1,2)
function str(a: string, b: string): Array<string> {
    return [a, b]
}
str('1', '2')

泛型优化

语法为函数名字后面跟一个<参数名> 参数名可以随便写 例如我这儿写了T

当我们使用这个函数的时候把参数的类型传进去就可以了 (也就是动态类型)

function Add(a: T, b: T): Array<T> {
    return [a, b]
}
Add<number>(1, 2)
Add<string>('x', 'y')

我们也可以使用不同的泛型参数名,只要在数量上和使用方式上能对应上就可以。

function Sub<T,U>(a: T, b: U): Array<T, U> {
    const params: Array<T|U> = [a, b]
    return params
}
Sub<Boolean, number>(false, 1)

定义泛型接口

声明接口的时候 在名字后面加一个<参数>

使用的时候传递类型

interface MyInter<T> {
    (args: T): T
}

function fn<T>(arg: T): T {
    return arg
}

let result: MyInter<number> = fn

result(132)

对象字面量泛型

let foo: { <T>(arg: T): T>
foo = function <T>(arg: T): T {
    return arg
}

foo(123)

泛型约束

我们期望在一个泛型的变量上面获取其length参数,但是,有的数据类型是没有length属性的

function getLength<T>(arg: T) {
    return arg.length
}

image.png

这时候我们就可以使用泛型约束

于是,我们就得对使用的泛型进行约束,我们约束其为具有length属性的类型,这里我们会用到interface,代码如下

interface Len {
    length: number
}

function getLength<T extends Len>(arg: T) {
    return arg.length
}

getLength<string>('123')

使用keyof 约束对象

其中使用了TS泛型和泛型约束。首先定义了T类型并使用extends关键字继承object类型的子类型,然后使用keyof操作符获取所有T类型的所有键,它的返回类型是联合类型,最后用extends关键字约束keyof联合类型的子类型

function prop<T, K extends keyof T>(obj: T, key: K) {
    return obj[key]
}

let o = { a: 1, b: 2, c: 3 }

prop(o, 'a')
prop(o, 'd') //此时就会报错发现找不到

泛型类

声明方法跟函数类似名称后面定义<类型>

class Sub<T> {
    attr: T[] = [];
    add(a: T): T[] {
        return [a]
    }
}

let s = new Sub<number>()
s.attr = [1, 2, 3]
s.add(123)

let str = new Sub<string>()
str.attr = ['1', '2'. '3']
str.add('123')