官方是这样介绍的:
软件工程中,我们不仅要创建一致的定义良好的API,同时也要考虑可重用性。 组件不仅能够支持当前的数据类型,同时也能支持未来的数据类型,这在创建大型系统时为你提供了十分灵活的功能。
在像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。
从上面的信息概括为泛型是支持多种类型的变量,根据用户需求灵活的变动,达到复用组件的效果。
在实际开发中,有一个函数是同样的逻辑,只是因为类型的不同,就要再写一个函数,这样并没有达到代码复用的原则。正好泛型就可以用来解决这种问题。
现在有一个处理数组的函数,这里只是简单的返回,当做进行处理
function formatArr(arr:Array<string>):Array<string>{
return arr.map(item=>item)
}
如果这时候有其他类型的数组需要同样的操作,而 formatArr 只接受字符串数组,我们有什么方法来解决呢?
函数接受一个任意类型的数组,这确实能够解决问题,但是也失去了类型检查的意义
function formatArr(arr:Array<any>):Array<any>{
return arr.map(item=>item)
}
重新再写一个同样逻辑的函数,这看起来就不妥。如果还要接受更多的类型,而函数内部的逻辑复杂,这样重新定义多个同样逻辑的函数,会显得代码的冗余
function formatArr2(arr:Array<number>):Array<number>{
return arr.map(item=>item)
}
面对这种需要接受多类型的函数,泛型才是正解。因为泛型的灵活性,我们不必在函数定义时就定义类型,而是执行时由使用者规定类型,达到代码复用的原则。
function formatArr<T>(arr:Array<T>):Array<T>{
return arr.map(item=>item)
}
formatArr<string>(['1', '2', '3'])
formatArr<number>([1, 2, 3])
定义函数 formatArr 时,在函数名后定义一个类型变量 <T>,同时参数数组项也接受 T 类型的值。
由于 <T> 是一个变量,在使用函数时,使用者传入的类型即为 <T> 的类型。
尖括号内的变量名并不是固定的,可以自定义,一般都是大写
泛型类实例化传入的泛型类型,可以在整个作用域中使用该泛型类型,但要注意的是类的静态属性无法使用泛型类型
class Handsome<T>{
//static myname:T = 'Jack' 静态成员不能引用类类型参数
girlfriend: Array<T>
constructor(){
this.girlfriend = []
}
addGirlfriend(name:T){
this.girlfriend.push(name)
}
getAllGirlfriend():Array<T>{
return this.girlfriend
}
}
let handsome = new Handsome<string>()
handsome.addGirlfriend('Julia')
handsome.addGirlfriend('Vivian')
//handsome.addGirlfriend({name:'Ellie'}) 类型“{ name: string; }”的参数不能赋给类型“string”的参数
handsome.getAllGirlfriend() // ['Julia', 'Vivian']
使用泛型约束来对 formatArr 做一些改造,改造后的函数功能为对传入的参数进行切片,返回除第一项的数据。
interface Slice{
slice:Function;
}
function formatArr<T extends Slice>(arg:T):T{
return arg.slice(1)
}
formatArr([1,2,3])
formatArr('hello')
但并不是每个类型都有 slice 方法,这时候就需要对泛型进行约束,规定只有slice 方法的参数才可以传入。
为此,定义一个含有 slice 方法的接口,使用这个接口和 extends 关键词实现约束。
这里可能你会想到接口继承,因为接口继承也使用了extends 关键词,但在泛型约束里并不是表示继承关系。
泛型在typescript中是很重要的一点知识,理解并应用泛型,可以使我们的代码更加灵活。所以在编程时要多想想是否能够使用泛型来优化,让代码的复用性最大化。
原文:https://www.cnblogs.com/chanwahfung/p/11965469.html