typescript之泛型的学习

131 阅读2分钟

前言
出于扩展函数的复用性的考虑,接口不仅要支持当前的数据类型,也需要支持未来的数据类型。
也就是说我们可以在编码(调用方法、实例化对象)时,指定数据类型。

泛型变量

函数的返回值需要与参数的数据类型一致

示例如下:

function Identity <T>(arg:T):T{//T可以理解为正则表达式的捕获,获取到了参数的数据类型之后,也就确定了返回值的类型
	return arg
}
//返回传入的字符串
let a:string = Identity<string>("paodan")
console.log(a)//paodan
//返回传入的number
let b:number = Identity<number>(20)
console.log(b)//20

泛型接口

上面的例子也可以通过泛型接口来指定泛型类型

示例如下:

interface IdentityFunc{
    <T>(arg:T):T
}
let c:IdentityFunc = function <T> (arg:T){
    return arg
}
console.log(c("hello world!"))//hello world

我们可能想把泛型参数当做整个接口的一个参数,这样我们就能清楚的知道使用的具体是哪个泛型类型(比如IdentityFunc<string>而不只是IdentityFunc),这样接口里的其他成员也能知道这个参数的类型了。
代码如下:

interface IdentityFunc<T>{
    (arg:T):T
}
let c:IdentityFunc<string> = function (arg){
    return arg
}
console.log(c("hello world!"))//hello world

泛型类

泛型类和泛型接口看起来差不多,泛型类的写法是 类名后面跟着<T>

class Generic <T>{
    zeroValue:T; //注意:此处用";"而不是","
    add:(x:T,y:T)=>T;
}
// 实现一个数字的add方法
let num = new Generic <number>();//错误写法:let num:number = new Generic <number>();
num.zeroValue = 0;
num.add = function(x,y){
	return x+y
}
let a:number = num.add(1,2)
console.log(a)
console.log("zeroVlue",num.zeroValue)

//实现字符串拼接的方法
let str = new Generic<string>();
str.zeroValue = ""
str.add = function(x,y){
	return x+y
}
let b:string = str.add("hello","world")
console.log(b)
console.log("zeroValue",str.zeroValue)

泛型约束

在某些时候需要指定某些特定的数据类型以及属性
如下示例,约束传递的参数需要有length属性

interface identityProp{
  length:number,
  age:number
}
function abc<T extends identityProp>(arg:T):T{
  console.log(arg.length)
  return arg
}
abc("Hello!")//6
abc(1)//报错:Type 'number' does not satisfy the constraint 'identityProp'  
//identityProp接口中指定两个属性的情况
interface identityProp{
  length:number,
  age:number
}
abc({length:2})//报错:Property 'age' is missing in type '{ length: number; }' but required in type 'identityProp'.

参考链接
学习Typescript