探讨TypeScript中的泛型 | 青训营

66 阅读4分钟

简介

TypeScript 是 JavaScript 语言的扩展,它使用 JavaScript 运行时和编译时类型检查器。

TypeScript 提供了多种方法来表示代码中的对象,其中一种是使用接口。TypeScript 中的接口有两种使用场景:您可以创建类必须遵循的约定,例如,这些类必须实现的成员,还可以在应用程序中表示类型,就像普通的类型声明一样。

泛型语法

泛型出现在尖括号内的 TypeScript 代码中,格式为,其中 T 表示传入的类型。可以理解为 T 类型的泛型。

在这种情况下,T 将以与函数中参数相同的方式运行,作为将在创建结构实例时声明的类型的占位符。因此,尖括号内指定的泛型类型也称为泛型类型参数或只是类型参数。多个泛型类型也可以出现在单个定义中,例如 <T, K, A>。 泛型可以出现在函数、类型、类和接口中。本教程稍后将介绍这些结构中的每一个,但现在将使用一个函数作为示例来说明泛型的基本语法。

将泛型与函数一起使用

将泛型与函数一起使用的最常见场景之一是当有一些代码不容易为所有用例键入时。为了使该功能适用于更多情况,可以包括泛型类型。

在此步骤中,将运行一个恒等函数示例来说明这一点,还将探索一个异步示例,了解何时将类型参数直接传递给您的泛型,以及如何为泛型类型参数创建约束和默认值。

分配通用参数

下面的示例函数,它返回作为第一个参数传入的内容:

function identity(value) {
  return value;
}

还可以添加以下代码以使函数在 TypeScript 中类型安全:

function identity<T>(value: T): T{
  return value;
}

当你的函数变成了一个泛型函数,它接受泛型类型参数 T,这是第一个参数的类型,然后将返回类型设置为与 : T 相同,一下代码实现这个功能。

function identity<T>(value: T): T {
  return value;
}

const result = identity(123);

结果的类型为 123,这是传入的确切数字。这里的 TypeScript 从调用代码本身推断泛型类型。这样调用代码不需要传递任何类型参数。也可以显式地将泛型类型参数设置为想要的类型:

function identity<T>(value: T): T {
  return value;
}

const result = identity<number>(123);

直接传递类型参数

直接传递类型参数在使用自定义类型时也很有用

type ProgrammingLanguage = {
  name: string;
};

function identity<T>(value: T): T {
  return value;
}

const result = identity<ProgrammingLanguage>({ name: "TypeScript" });

默认类型参数

调用代码始终必须提供类型参数。如果调用代码不包含泛型类型,则 ResultType 将绑定为未知。以下面的实现为例:

async function fetchApi<ResultType>(path: string): Promise<ResultType> {
  const response = await fetch(`https://example.com/api${path}`);
  return 
response.json();
}

const data = await fetchApi('/users')

console.log(data.a)

export {}

类型参数约束

在某些情况下,泛型类型参数需要只允许将某些形状传递给泛型。要为您的泛型创建额外的特殊层,您可以对您的参数施加约束。

将泛型与接口、类和类型一起使用

在 TypeScript 中创建接口和类时,使用泛型类型参数来设置结果对象的形状会很有用。

通用接口和类

要创建通用接口,您可以在接口名称之后添加类型参数列表:

interface MyInterface<T> {
  field: T
}

这声明了一个接口,该接口具有一个属性字段,其类型由传递给 T 的类型确定。

对于类,语法几乎相同:

class MyClass<T> {
  field: T
  constructor(field: T) {
    this.field = field
  }
}

通用接口/类的一个常见用例是当您有一个字段,其类型取决于客户端代码如何使用接口/类时。

使用泛型创建映射类型

在使用 TypeScript 时,有时您需要创建一个与另一种类型具有相同形状的类型。这意味着它应该具有相同的属性,但属性的类型设置为不同的东西。对于这种情况,使用映射类型可以重用初始类型形状并减少应用程序中的重复代码。

在 TypeScript 中,这种结构被称为映射类型并依赖于泛型。