TypeScript 中文教程之泛型----翻译自ts官网
在不使用泛型的情况下,定义一个函数并明确他的参数类型:
function identity(arg: number): number {
return arg;
}
或者使用一个不限类型的 any :
function identity(arg: any): any {
return arg;
}
使用 any 相当于一个不限类型的泛型,函数可以接受并返回所有类型,这样做的问题在于丢失了参数和返回值的类型信息,无法从字面上看出
这个函数接收和返回的类型,实际上也就失去了使用 TS 的意义。
🔯 泛型:使用一个特殊的变量指定类型,这个变量只用于类型上,不用于具体的值。
function identity<Type>(arg: Type): Type {
return arg;
}
给identity函数添加了一个类型变量 Type ,这个类型变量可以追踪入参和返回值,并检查类型的一致性。
在调用这个函数时,可以使用 <> 传入类型,也可以使用函数 () 中的参数自动判断类型,一下两种效果一样:
给定泛型类型:let output = identity<string>('myString');
根据参数自动判断:let output = identity('myString');
泛型在使用时,应该注意他的使用’边界‘:
function loggingIdentity<Type>(arg: Type): Type {
console.log(arg.length); // 这里会有问题,不是所有的Type都有 length 这个属性的,比如 number
return arg;
}
上面这个函数通常我们期望传入的参数是一个 array ,所以我们可以这样定义:
function loggingIdentity<Type>(arg: Type[]): Type[] {
console.log(arg.length);
return arg;
}
Type 变量可以是参数的一部分,并非所有泛型Type都需要直接引用。
🔯 泛型接口
使用泛型类型函数创建另一个函数,和使用一个非泛型函数类似:
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: <Input>(arg: Input) => Input = identity;
泛型类型的变量名可以使用不同的名称。
我们还可以使用函数签名替换上面的写法:
let myIdentity: { <Input>(arg: Input): Input } = identity;
转变为接口的形式编写泛型函数
interface GenericIndentityFn {
<Type>(arg: Type): Type;
}
function indentity<Type>(arg: Type): Type {
return arg;
}
let myIndentity: GenericIndentityFn = indentity
这种方式在使用时无法感知到泛型到底是什么类型,换个写法:
把泛型参数作为整个接口的参数,写到外面,如果你使用过 react 中的 class 对这种写法或许较为熟悉了,:
interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
function indentity<Type>(arg: Type): Type {
return arg;
}
let myIndentity: GenericIndentityFn<number> = indentity
🔯 泛型类
泛型类和泛型接口写法相似,类名紧跟尖括号的方式表达泛型类
class GenericaNumber<NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumTyep) => NumType;
}
let myGenericNumber = new GenericaNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
}
类在使用泛型时,应该注意:泛型只用于实例方法和实例属性上,不用于静态属性和静态方法上。
posted on 2022-02-25 14:50 Deflect-o-Bot 阅读(129) 评论(0) 编辑 收藏 举报