点击上方“青年码农”关注
回复“特效源码”可获取各种资料
当我们定义一个变量或者重构之前的JavaScript代码不确定类型的时候,一般会有两种解决方式。
1. 使用any
简单粗暴,任何类型都可以,但是失去了ts类型保护的优势。
2. 使用泛型
不预先指定具体的类型,而是在使用的时候在指定类型限制的一种特性。
看下面的这个函数
function identity(arg: any): any {
return arg;
}
identity这个函数接收一个参数,这个参数是任意类型,返回的结果也是任意类型.。如果这个函数的传入的类型和返回的类型相同,使用any类型,就无法实现这个约束。
因此,需要一种方法使返回值的类型与传入参数的类型是相同的。这里,我们使用了类型变量,它是一种特殊的变量,只用于表示类型而不是值。
function identity<T>(arg: T): T {
return arg;
}
没有明确要求传递参数的类型,虽然也是任意类型,但是保证了传入类型和返回类型的一致性。
let output = identity<string>("myString");
使用<>明确string类型,作为参数传给函数。另外一种是类型推论,这种方法更普遍,
let output = identity("myString");
调用函数我们没有明确传入的类型,编译器帮我们去识别,并设置它的类型。如果复杂的情况,编译器不能自动判断类型的话,那就需要我们手动设置。
通过上面简单的例子,我们可以很好的理解这两个区别,打个比方,你去超市买东西,你给的是钱,售货员给你的是商品,类型不同,可以用any。如果你去超市破零钱,那售货员给你的还是钱,类型相同,可以用泛型<T>。
any就不用过多讲解使用方式,和其他类型一样,主要说说泛型的使用
1.在函数中使用
function echo<T>(arg:T):T{
return arg
}
const result=echo(true)
很好理解,给的什么,返回的就是什么。
function swap<T,U>(arg:[T,U]):[U,T]{
return [arg[],arg[]]
}
const result2=swap(['string',])
和上面类似,传递两个参数,返回时做了调换。
2.在类中使用
class Animal<T> {
name:T;
constructor(name: T){
this.name = name;
}
action<T>(say:T) {
console.log(say)
}
}
let cat = new Animal('cat');
cat.action('mimi')
实例化Animal的时候,传递的参数是string类型,因此在调用cation方法时也要是相同的类型。
3.在接口中使用
interface KeyPair<T,U>{
key:T,
value:U
}
let kp1:KeyPair<number,string>={key:,value:'string'}
let kp2:KeyPair<string,number>={key:'abc',value:}