Skip to content

泛型

泛型可以比喻成一个类型占位符,在使用的时候再去指定类型的一种特性。它是一种抽象的类型,,区别于平时的TS类型,泛型更像是对类型的编程。

img

基本使用

假设我们需要一个函数获取传入数组参数的第一项,但是不知道参数和返回值的类型,第一印象会写成下面这样:

typescript
function getFirstIte(arr: any[]): any {
  return arr[0];
}

type Person = {
  name: string
  age: number
}
const person: Person = [{name:"张三",age:"20"}]

getFirstItem(person)

这虽然是符合需求了,但是any的类型会让TS丢失类型检查的功能,可以使用泛型动态捕获类型,指定参数和返回值的类型:

typescript
function getFirstItem<T>(arr: T[]): T {
  return arr[0];
}

// ...

getFirstItem<Person>(person)

这段代码的意思是:函数接收一个泛型T,在调用这个函数的时候Person将会作为T实际类型传递,会成为参数以及返回值的类型。

函数

三种定义函数的方式均支持使用泛型。

typescript
/* 函数声明 */
function identity<T>(arg: T): T {
  return arg;
}

/* 函数表达式 */
const identity = function <T>(arg: T): T {
  return arg;
};

/* 箭头函数 */
const identity = <T>(arg: T): T => {
  return arg;
};

接口

在接口中使用泛型。

typescript
interface IProps<T>{
  name: string
  age: T
}

const props: IProps = {
  name: "张三",
  age: 20
}

type

在类型别名中使用泛型。

typescript
type Params<T> = T;

默认值

给泛型一个默认值,如果泛型不传参,它会使用默认值,可以完全类比于函数的默认参数来理解。

typescript
function identity<T = string>(arg: T): T {
  return arg;
}

identity("abc") // T: string

还可以对类型进行约束,表示传入的类型必须是某个类型的子类或包含某个属性:

typescript
function getLength<T extends { length: number }>(arg: T): T {
  return arg.length;
}

getLength("abc") // OK,string 包含 length 属性,静态检查过关
getLength(123) // Error,number 不包含 length 属性,TS 检查错误

类结合泛型使用,可以给类的属性/方法在实例化时添加类型,需要注意的是,类的静态属性/方法不能使用泛型类型。

typescript
class GenericNumber<T> {
  zeroValue: T
  add: (x: T, y: T) => T
}

const myGenericNumber = new GenericNumber<number>()
myGenericNumber.zeroValue = 0
myGenericNumber.add = function (x, y) {
  return x + y
}

如有转载或 CV 的请标注本站原文地址