前言
出于扩展函数的复用性的考虑,接口不仅要支持当前的数据类型,也需要支持未来的数据类型。
也就是说我们可以在编码(调用方法、实例化对象)时,指定数据类型。
泛型变量
函数的返回值需要与参数的数据类型一致
示例如下:
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