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;
}

类在使用泛型时,应该注意:泛型只用于实例方法和实例属性上,不用于静态属性和静态方法上。

class GenericNumber<NumType> {
  static _zeroValue: NumType;  // 🤢
  static _add: () => NumType;  // 🤢
  zeroValue: NumType;
  add: (x: NumType, y: NumType) => NumType;

}

posted on 2022-02-25 14:50  Deflect-o-Bot  阅读(122)  评论(0编辑  收藏  举报