TypeScript学习笔记:泛型

只是学习笔记。

遇到复杂的类型定义,就得用TypeScript 中的泛型了。

其实泛型可以说是类型的变量。从最简单的例子看起

function identity<T>(arg: T): T {
    return arg;
}

这个函数只是想表达一下,输入啥类型就返回啥类型。然而输入类型可能有很多种,这时候就需要一个泛型,T是一个类型的变量。

function identity<T>(arg: T[]): T {
    return arg[1];
}

这个可以更直观看出T是个类型的变量,输入T类型的数组,输出其中一个元素。

调用时,可以给泛型传递类型。

identity<string>(['1']);

但没有必要,ts可以自动推导出类型。

identity(['1']);

当函数的类型比较复杂的时候可以定义一个泛型接口

interface GenericIdentityFn {
    <T>(arg: T): T;
}

随后函数的返回类型就好说了

function identity<T>(arg: T): T {
    return arg;
}

let myIdentity: GenericIdentityFn = identity;

定义了泛型接口之后我们就可以规定具体可以传入哪些玩意了

给这个接口加个泛型

interface GenericIdentityFn<T> {
    (arg: T): T;
}

这样T就从“实现此接口的函数的传入类型”变成了“实现接口时规定的类型”

const myIdentity: GenericIdentityFn<string | number> = (arg: string) => arg;

这里规定,实现这个接口的函数必须接收字符串或者数字。

赋值的这个函数接受的是字符串,所以类型检查通过。

还可以使用泛型来对传入参数进行更详细的限制。例如,我们只要求传入的这个参数拥有length类型,而不管是数组还是字符串还是类数组的玩意。

interface Lengthwise {
    length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
    console.log(arg.length);
    return arg;
}

更进阶的,例如要做一个从object中取值的函数,我们想要key必须是这个object中存在,这样的需求竟然也可以实现。

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

let x = { a: 1, b: 2, c: 3, d: 4 };

getProperty(x, "a"); // okay
getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'.

https://zhongsp.gitbooks.io/typescript-handbook/content/doc/handbook/Generics.html

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注