官方文档
介绍
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
使用示例
ts中泛型就是在编译期间不确定方法使用的类型(广泛之意思),在方法调用时,指定泛型具体指向类型。
// 1 泛型函数
// 获取数组中最小值 (数字)
function getMinNumber(arr:number[]):number{
var min=arr[0];
arr.forEach((value)=>{
if(value<min){
min=value;
}
});
return min;
}
// 获取数组中最小值 (字符串)
function getMinStr(arr:string[]):string{
var min=arr[0];
arr.forEach((value)=>{
if(value<min){
min=value;
}
});
return min;
}
// 获取数组中最小值 (泛型)
function getMin<T>(arr:T[]):T{
var min=arr[0];
arr.forEach((value)=>{
if(value<min){
min=value;
}
});
return min;
}
// 不论数组元素是数字或者字符串,getMin都可以返回数组最小值
console.log(getMin([1, 3, 5, 7, 8]));
console.log(getMin(["tom","jerry","jack","sunny"]));
// 限定数组元素是数字
console.log(getMin<number>([1, 3, 5, 7, 8]));
// 限定数组元素是字符串
console.log(getMin<string>(["tom","jerry","jack","sunny"]));
// 2 泛型函数接口
interface IGetMinFn {
<T>(arg:T[]): T;
}
const getMinFn:IGetMinFn = getMin;
console.log(getMinFn([1, 3, 5, 7, 8]));
console.log(getMinFn(["tom","jerry","jack","sunny"]));
console.log(getMinFn<number>([1, 3, 5, 7, 8]));
console.log(getMinFn<string>(["tom","jerry","jack","sunny"]));
interface IGetMinFn_<T> {
(arg:T[]): T;
}
const getMinNumberFn:IGetMinFn_<number> = getMin;
console.log(getMinNumberFn([1, 3, 5, 7, 8]));
const getMinStrFn:IGetMinFn_<string> = getMin;
console.log(getMinStrFn(["tom","jerry","jack","sunny"]));
// 2 泛型类
class GetMin<T>{
arr:T[];
constructor (arg?:T[]){
this.arr = arg || []; // 使用传入初始数组 或 空数组
}
add(num:T):T[]{
this.arr.push(num) // 向数组添加元素
return this.arr;
}
min():T {
let min = this.arr[0];
this.arr.forEach(function (value) {
if(value < min){
min=value;
}
});
return min;
}
}
const getMinNumberObj = new GetMin<number>([1,3,5]);
getMinNumberObj.add(7);
getMinNumberObj.add(8);
console.log(getMinNumberObj.min());
const getMinStrObj = new GetMin<string>(["tom","jerry"]);
getMinStrObj.add("jack");
getMinStrObj.add("sunny");
console.log(getMinStrObj.min());
//4 泛型类接口
// 类
class Item{
key:number;
value:string;
}
// 泛型类
class Items<T>{
itemArr:T[]
constructor(items?:T[]){
this.itemArr = []
if(items){
this.itemArr = items
}
}
}
//泛型接口
interface ICommand<T> {
addItem(obj:T):void;
delItem(index:number):void;
updateItem(index:number, obj:T):void
getItem(index:number):T;
}
// 使用类作为泛型,继承泛型类,实现泛型接口
class CommandItem extends Items<Item> implements ICommand<Item>{
constructor(items?:Item[]){
super(items)
}
addItem(obj:Item){
this.itemArr.push(obj)
}
delItem(index:number){
this.itemArr.splice(index,1)
}
updateItem(index:number, obj:Item){
this.itemArr.splice(index,1,obj)
}
getItem(index:number):Item{
return this.itemArr[index]
}
}
const commandItemObj= new CommandItem([{key:0,value:'test'}]);
const obj = commandItemObj.getItem(0);
console.log(obj);
// 5 泛型约束
interface ILength {
length: number
}
// 使用ILength约束泛型T
function logLength<T extends ILength>(arg:T):T{
console.log(arg.length);
return arg;
}
// 被约束的泛型只能是包含length属性的数据类型
logLength([1,2,3]);
logLength({length:10});