haohaio
努力学习,艰苦奋斗
写写代码,记记笔记
泛型变量
我们可以在不知道函数参数类型的情况下,使用泛型来保证返回值的类型与传入参数的类型相同:
function identity<T>(arg: T): T { return arg; }
|
我们使用泛型创建了泛型函数后,可以这样调用:
let output = identity<string>("myString");
|
或者:
let output = identity("myString");
|
我们还可以把我们把泛型变量 T 当做类型的一部分使用:
function loggingIdentity<T>(arg: Array<T>): Array<T> { console.log(arg.length); return arg; }
|
function loggingIdentity<T>(arg: T[]): T[] { console.log(arg.length); return arg; }
|
泛型接口
我们可以使用接口来定义函数类型:
interface GenericIdentityFn { <T>(arg: T): T; }
function identity<T>(arg: T): T { return arg; }
let myIdentity: GenericIdentityFn = identity;
|
我们还可以把泛型参数当作整个接口的一个参数,这样我们就能清楚的知道使用的具体是哪个泛型类型:
interface GenericIdentityFn<T> { (arg: T): T; }
function identity<T>(arg: T): T { return arg; }
let myIdentity: GenericIdentityFn<number> = identity;
myIdentity(123); myIdentity("123");
|
泛型类
泛型类看上去与泛型接口差不多。 泛型类使用( <>)括起泛型类型,跟在类名后面。
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; }
let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function (x, y) { return x + y; };
|
可以看到,类中只能使用同一种类型。
泛型约束
可以看到下面这个例子中:我们想访问 arg 的 length 属性,但是编译器并不能证明每种类型都有 length 属性,所以就报错了。
function loggingIdentity<T>(arg: T): T { console.log(arg.length); return arg; }
|
当我们想要限制函数去处理任意带有.length属性的所有类型。 我们需对传入的类型进行约束,要求传出的属性至少包含 length 这一属性。我们可以使用接口和 extends 关键字来实现约束:
interface Lengthwise { length: number; }
function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; }
loggingIdentity({ length: 3, value: "123" });
|
使用类型参数进行约束
声明一个类型参数,且它被另一个类型参数所约束:
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"); getProperty(x, "m");
|
本文代表个人观点,内容仅供参考。若有不恰当之处,望不吝赐教!