Typescript 泛型
当我们的参数是一个不确定的数据类型的时候,且返回值和传入的参数是同一种数据类型,我们就可以使用泛型,我们也可以使用any,但是any不能确保输入和输出是同一种数据类型,会丢失一些信息
基本使用
下面是一个最简单的泛型例子,T
可以是任何名字,可以当它是一个变量。
function identity<T>(arg: T): T {
return arg;
}
使用的时候,指定具体的泛型变量类型,即可保证输出也是string
类型
let output = identity<string>('hello')
console.log(output)
我们不需要手动指定泛型的变量类型,ts
会帮我们自动检测传过去的是什么类型
let output1 = identity('world')
console.log(output1);
使用泛型变量,下面的代码会报错,因为arg
指定类型是T
,但是T
是泛型,不确定传进来的是很么类型,如果是数字就没有length
属性,因此会报错
function getLength<T>(arg: T): T {
console.log(arg.length);
return arg
}
使用<T>
指定了泛型,传入的参数规定为泛型组成的数组,返回值也是一样,就可以使用了
function getLength1<T>(arg: T[]): T[] {
console.log(arg.length);
return arg
}
// 这种方式也可以
function getLength2<T>(arg: Array<T>): Array<T> {
console.log(arg.length);
return arg
}
箭头函数形式
const getLength3 = <U>(arg: Array<U>): Array<U> => { return arg }
let len = getLength3([1, '2', true])
console.log(len);
在泛型里使用类类型
以下代码函数create
接收一个名为C
的类,返回C
的实例,如果不是传入的类,代码将会报错
function create(C) {
return new C()
}
使用泛型队该函数进行约束,参数c
后面{new ()}
表示c
是一个类,可以new
,再加上一个传入类型和返回类型,就可以这么写
function createC<T>(c: { new(): T }): T {
return new c();
}
泛型函数接口
定义泛型函数接口,可以有以下两种形式
- 泛型定义在函数中,这种写法的特点是用户调用的时候,可以给定任意数据类型
interface ConfigFn { <T>(value: T): T; } function getData<T>(value: T): T { console.log(value); return value } const myGetData: ConfigFn = getData // 函数实现 myGetData<string>('baihuzi.com') myGetData<number>(10086)
- 泛型定义在接口中,推荐这种写法,这种方式提前指定泛型的数据类型
interface ConfigFn1<T> { (value1: T): T; // 泛型接口 } // 函数实现,箭头函数写法 // 提前执行函数需要的数据类型,这里使用的时候只能传字符串类型的数据 const myGetData1: ConfigFn1<string> = value1 => { console.log(value1); return value1 } myGetData1('www.baihuzi.com') // myGetData1(123) // error
泛型类
泛型类使用<>
括起泛型类型,跟在类名后面。
class GenericNumber<T> {
zeroValue: T;
constructor(value: T){
this.zeroValue = value
}
show():T {
return this.zeroValue
}
}
let myGenericNumber = new GenericNumber<number>(123);
myGenericNumber.zeroValue = 0;
myGenericNumber.show()
let stringNumeric = new GenericNumber<string>('string');
stringNumeric.zeroValue = "";
myGenericNumber.show()
泛型约束
泛型约束规定泛型必须要有哪些属性,使用extends
关键字进行定义,理解起来就是泛型T
继承自BoxConf
,因此泛型T
上必须要有size
和length
属性,我们在传参的时候就需要带上这些属性
interface BoxConf {
size: string
length: number
}
// 泛型约束,必须要包含JJ中的属性
function createHuman<T extends BoxConf>(what: T): T {
return what
}
createHuman({
name: 'Jack',
age: 18,
size: 'large', // 缺少这个会报错
length: 18 // 缺少这个也会报错
})
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 289211569@qq.com