LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

一文打通TypeScript 泛型

freeflydom
2025年6月9日 11:49 本文热度 68

前言

人们经常听说 TypeScript 就是添加了类型和附加功能的 JavaScript,但却没有人谈论这些“附加功能”,仿佛他们害怕自己会发现什么似的。为了提高应用程序的灵活性和长期可扩展性,泛型被引入 Web 开发中,作为一种工具来复用组件。

什么是 TypeScript 泛型?

这里有这样一个有趣的场景:一位 TypeScript 开发者正在和一位 JavaScript 开发者讨论他们在 Web 开发中最喜欢使用的功能。聊天中,他们提到了“泛型”这个词。JavaScript 开发者感到困惑,问泛型是什么。TypeScript 开发者回答说:“ TypeScript 泛型是 Web 开发中用于创建可复用组件的工具。它可以帮助开发者创建能够处理多种数据类型的组件,而无需为特定组件显式定义每种类型。”

假设一位开发人员创建了一个特定类型的组件number,但之后在代码库中,他想复用该组件的功能来接受其他数据类型的输入,比如string。TypeScript 泛型无需切换组件来接受string数据类型,而是提供了为单个组件接受多种类型的灵活性。是不是很有意思?所以,如果你一直在寻找实现这一点的方法,那么你来对地方了!

为什么要使用 TypeScript 泛型?

代码可重用性是使用 TypeScript 泛型的好处之一,但这还不是全部。其他主要好处包括:

  • 编译时类型检查:使用泛型时,必须在定义变量、函数或类后指定数据类型。指定的数据类型会在到达编译器之前进行检查。这可以节省开发时间,因为类型错误会更早地被突出显示。
  • 提高代码可读性:在大型项目或团队合作中,一项关键的工程实践是确保代码易于阅读。由于 TypeScript 泛型是明确定义的,因此使用泛型可以提高代码可读性。
  • 消除类型推断: 泛型不再允许 TypeScript 编译器通过类型推断来推断类型,而是消除了类型推断的需要。这提高了代码安全性。
  • 消除 any 类型:确保变量兼容多种类型的一种方法是赋予其 any 类型。这会告诉编译器:“嘿,这个变量应该适用于任何数据类型!” 然而,这是一种不好的做法,因为没有进行类型检查,可能会导致不必要的结果。泛型提供了一种在确保类型安全的同时接受多种数据类型的方法。

基本语法和工作原理

我们已经了解到,使用泛型可以实现单个变量接受多种数据类型,而不像使用any关键字那样。考虑下面的代码块:

// type of number is defined
let size: number = 12;
// size accept type of string?
let size = "Twelve";
// error

在上面的代码片段中,我们将变量 size 的类型指定为数值,其值为12,然后尝试将变量重新赋值为,但采用字符串格式。由于我们尝试将变量赋值为类型,而该变量最初被定义为接受数据类型12,因此会引发错误。我们如何实现一个实例,使变量能够同时接受和两种类型?string``Twelve``number``number``string

使用任何数据类型

将多种数据类型的值赋给单个变量的一种方法是使用any数据类型。请考虑下面的代码块:

//code sample
let sample: any;
//string data type
sample =
  "Convert from one programming language to another using the Pieces App";
//number data type
sample = 2;
sample = true;

在这里,我们创建一个名为 sample 的变量,其any类型为 。这意味着该变量可以接受任何数据类型。在我们的代码片段中,我们分配了一个string类型,表示“使用 Pieces App 从一种编程语言转换为另一种编程语言”,一个number类型为 value 2,以及一个布尔类型为 value true

在 TypeScript 中,将其他数据类型的值赋给预定义变量会引发错误,但 TypeScriptany提供了解决方案。any然而,不建议使用 TypeScript 数据类型,因为它会绕过类型检查,并在运行时带来类型不匹配的风险。

泛型的使用 - 泛型函数

TypeScript 允许单个变量使用多种数据类型的另一种方式是使用泛型。泛型函数构成了泛型的主要用途。假设我们现在在 TypeScript 中创建一个接受数字类型的函数。具体操作如下:

function numberType(arg: number): number {
  return arg;
}

这里,为了避免抛出错误,返回值的类型必须是数字。有时,我们不知道返回的具体值。使用该any类型将使函数接受该值,但我们不知道返回的类型。这就是 TypeScript 中泛型的作用所在。它允许接受任何数据类型,同时指定被接受的类型。让我们看看如何实现这一点:

function anyType<Type>(arg: Type): Type {
  return arg;
}

在上面的代码片段中,我们添加了一个Type嵌入的 Type 变量<>,这是 TypeScript 泛型的基本语法。当函数返回一个值时,Type可以通过 知道返回的确切类型。这是使用 TypeScript 泛型的好处之一——不再需要any类型。

创建通用函数

为了正确理解代码库中泛型的必要性,我们将创建一个基本的 TypeScript 泛型函数,它接受不同类型的数据。正如我们之前讨论过的,实现这一点的一种方法是使用any类型。在本节中,我们将讨论如何使用泛型来实现这一点。请考虑下面的代码块:

function genericsSample<T>(items: T[]): T[] {
  return new Array<T>().concat(items);
}
let numType = genericsSample<number>([10, 20, 30]);
let stringType = genericsSample<string>([
  "Pieces app",
  "A tool for developers",
]);
numType.push(80); // Correct
numType.push("Copy and save code snippets"); // Error
stringType.push(
  "Convert from one programming language to another using the Pieces App",
); // Correct
stringType.push(90); //Error
console.log(numType);
console.log(stringType);

在上面的代码块中,我们创建了一个用于连接两个元素的泛型函数。此代码片段旨在接受两种类型的数据:数字和字符串。此代码片段与包含泛型的代码片段的主要区别any在于,泛型函数会验证用户的数据类型。

在此代码片段中,我们创建了一个名为 的泛型函数genericsSample,它返回一个类型数组。之后,我们创建了两个变量,numType和接受一个数字数组,而接受一个字符串数组stringType。这样做的目的是在用户登录控制台之前验证用户的输入。numType``stringType

成功创建变量后,我们尝试向已创建的 TypeScript 通用数组中添加新项,以测试其是否有效。我们向 和 分别添加了一个字符串和一个数字numTypestringType这两个字符串分别是“复制并保存代码片段” 和“使用 Pieces App 从一种编程语言转换为另一种编程语言”, 它们是 Pieces 的一些用例。

在输出中,我们看到,当我们尝试将字符串添加到 anumType以及尝试将数字添加到 a 时,它会抛出一个错误stringType。让我们运行代码并查看输出:

在这里,我们看到,第一次将字符串传递给 numType 变量时会引发一个错误,而将数字传递给 stringType 变量时又会引发另一个错误。借助泛型,我们的代码可以在单个函数中验证多种数据类型的输入。

泛型类

除了创建函数之外,我们还可以创建 TypeScript 泛型类。定义类名后,在尖括号 (<>) 中指定泛型类型参数。请考虑以下代码块:

class GenericClass<T> {
  private genericField: T;
  constructor(value: T) {
    this.genericField = value;
  }
  getValue(): T {
    return this.genericField;
  }
}
//creating a class with a number type
const numType = new GenericClass<number>(27);
const getNum: number = numType.getValue();
console.log(getNum);
//creating a class with a string type
const stringType = new GenericClass<string>(
  "Convert from one programming language to another using the Pieces App",
);
const getString: string = stringType.getValue();
console.log(getString);

在这里,为了在我们的类中接受多种类型,我们在 TypeScript 中创建了一个泛型类,其类型参数为“T”,这样我们就可以指定要传递给它的任何类型(数字、字符串或任何其他类型)。在这段代码的第一个实例中,我们指定 GenericClass 的值应该是数字类型 27。在第二个实例中,我们指定 GenericClass 的值应该是一个字符串,内容为“使用 Pieces App 从一种编程语言转换为另一种编程语言” 。

TypeScript 通用接口

TypeScript 中的接口也支持泛型。这使我们能够创建接受多种数据类型的接口。假设我们要创建一个接受两种类型(数字和字符串)的泛型 TypeScript 接口。操作方法如下:

interface interfaceSample<T, U> {
  first: T;
  second: U;
}
const interfaceOne: interfaceSample<number, string> = {
  first: 20,
  second: "10",
};
const interfaceTwo: interfaceSample<string, boolean> = {
  first: "Generate code snippets using Pieces Co Pilot",
  second: true,
};
console.log(interfaceOne);
console.log(interfaceTwo);

这里,我们创建一个 TypeScript 泛型接口,其中包含两个类型参数“T”和“U”。这代表我们将要传入的类型的占位符。在 interfaceOne 变量中,我们传入数字类型和字符串类型。在 interfaceTwo 变量中,我们传入一个布尔类型和一个字符串类型,其含义为“使用 Pieces Copilot 生成代码片段” 。

TypeScript 泛型约束

虽然泛型适用于所有类型,但有时我们可能希望将函数、类或接口限制为仅使用单一类型。我们通过使用 TypeScript 泛型约束来实现这一点。我们可以使用一个示例接口来演示这一点:

interface ConstraintSample {
  sample: number;
}
function loggingIdentity<Type extends ConstraintSample>(test: Type): Type {
  console.log(test.sample); //
  return test;
}
loggingIdentity({ sample: 15, value: 10 });

通常,要获取值 10,我们只需调用 loggingIdentity(10) 函数即可,但在本例中,这行不通,因为我们添加了一个泛型约束,它为我们正在处理的类型增加了额外的特异性。在这里,要获取值 10,我们必须首先指定我们尝试调用的值中有一个 sample 属性。要调用约束中的任何值,我们需要指定与该值关联的所有属性。

转自https://juejin.cn/post/7512642238833557556


该文章在 2025/6/9 11:49:19 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2025 ClickSun All Rights Reserved