官网文档地址 https://www.typescriptlang.org/docs/handbook/generics.html
泛型
软件工程的一个主要部分是构建组件,这些组件不仅具有定义良好和一致的API,而且还具有可重用性。能够处理今天的数据和明天的数据的组件将为您提供构建大型软件系统的最灵活的能力。
在C#和Java等语言中,工具箱中用于创建可重用组件的主要工具之一是泛型也就是说,能够创建一个可以工作于多种类型而不是单个类型的组件。这允许用户使用这些组件并使用自己的类型。
通俗理解:泛型就是解决类、接口、方法的复用性、以及对不特定数据类型的支持
使用any类型可以实现复用,但是这样就放弃了类型检查的功能。
泛型函数
泛型类型在<>中指定,一般为类型变量T
function identity<T>(arg: T): T {
return arg;
}
添加了一个类型变量T身份函数,这T允许我们捕获用户提供的类型(例如:number),以便以后可以使用该信息。在这里,我们用T再次作为返回类型。在检查时,我们现在可以看到参数和返回类型使用相同的类型。这允许我们在函数的一边输入信息,然后将信息输出到函数的另一端。
=====
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = identity;
console.log(myIdentity<string>('2str'))
=====
function getData<T>(num:T):T{
return num;
}
console.log(getData<number>(2));// 具体类型调用时决定
=====
泛型类
泛型T,由实例化时指定的泛型确定
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; };
类的类型有两个方面:静态侧和实例端。泛型类只是实例端的泛型,而不是静态端的泛型,因此在使用类时,静态成员不能使用类的类型参数
创建一个描述约束的接口。在这里,我们将创建一个有一个.length属性,然后我们将使用此接口和extends关键字来表示我们的约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
把类作为参数类型来约束泛型类
//把类作为参数来约束数据传入的类型
class User{
username!:string;
password!:string;
}
class db<T>{
add(user:T):void{
console.log(user);
}
}
let user = new User();
user.username="xiaoxi";
user.password="123"
let dbObj = new db<User>();
dbObj.add(user);
泛型接口
interface ConfigFN{
<T>(value:T):T;
}
let getDate:ConfigFn = function<T>(value:T):T{
return value;
}
console.log(getDate<string>('123'));
=====
interface GenericIdentityFn<T> {
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<string> = identity;
console.log(myIdentity('xiaoxi'))