通过与 Jira 对比,让您更全面了解 PingCode

  • 首页
  • 需求与产品管理
  • 项目管理
  • 测试与缺陷管理
  • 知识管理
  • 效能度量
        • 更多产品

          客户为中心的产品管理工具

          专业的软件研发项目管理工具

          简单易用的团队知识库管理

          可量化的研发效能度量工具

          测试用例维护与计划执行

          以团队为中心的协作沟通

          研发工作流自动化工具

          账号认证与安全管理工具

          Why PingCode
          为什么选择 PingCode ?

          6000+企业信赖之选,为研发团队降本增效

        • 行业解决方案
          先进制造(即将上线)
        • 解决方案1
        • 解决方案2
  • Jira替代方案

25人以下免费

目录

TypeScript 中泛型怎么用

TypeScript 中泛型怎么用

TypeScript 的泛型用于在代码编写阶段即可预定义和重用代码,保证了类型的灵活性和可重用性、提高了代码的健壮性。在实践中,泛型允许我们定义函数、接口或类但延迟一部分类型的具体指定直到实际使用时。这使得相同的函数可以轻松适应不同的类型,而无需进行重复的代码编写。

以泛型在函数中的应用为例,一般而言,我们可能需要定义一个返回输入参数相同类型的函数。在没有泛型的情况下,我们可能需要为每种类型编写一个函数。而有了泛型,我们只需写一次就可以了。这不仅减少了代码量,也提升了代码的可维护性。

一、泛型基础用法

在 TypeScript 中,泛型可以应用于函数、接口、类之中。其最基本的用法是在函数中定义泛型。

函数中使用泛型

假设我们有一个函数,需要返回传入的任何类型的值。而且我们希望这个函数能够处理多种类型的数据,这时就可以使用泛型。

function identity<T>(arg: T): T {

return arg;

}

在这里,<T> 就是泛型的表示方式,它告诉 TypeScript 我们将使用泛型类型 T。这个函数的意思是,无论输入什么类型的 arg,都将返回相同类型的数据。

通过这种方式,当我们调用 identity 函数时,TypeScript 会自动判断出具体的类型。

let output = identity<string>("myString");

在此处,我们明确地指定了 Tstring 类型,因此输入 "myString" 将返回一个字符串。这样,我们使用一个函数就能处理多种类型,而不是为每一种可能的类型写一个新的函数。

接口中使用泛型

泛型也可以在接口中定义,这使得我们可以在定义接口时保持灵活性。

interface GenericIdentityFn<T> {

(arg: T): T;

}

function identity<T>(arg: T): T {

return arg;

}

let myIdentity: GenericIdentityFn<number> = identity;

这里,我们定义了一个泛型接口 GenericIdentityFn,该接口接受一个参数,返回类型与输入相同。然后我们将这个接口应用到 identity 函数上,通过 GenericIdentityFn<number> 明确地指明了这是一个接受 number 类型的函数。

二、泛型约束

在某些情况下,我们需要对泛型进行一些约束,以确保它们具有我们需要的结构或属性。

基本泛型约束

interface Lengthwise {

length: number;

}

function loggingIdentity<T extends Lengthwise>(arg: T): T {

console.log(arg.length); // Now we know it has a .length property, so no more error

return arg;

}

这里,我们使用 extends 关键字对泛型 T 进行了约束,T 必须符合 Lengthwise 接口。这样的话,我们就可以安全地访问 .length 属性,因为任何不具备 length 属性的数据都会在编译阶段报错。

在类中使用泛型约束

泛型不仅可以在函数或接口中使用,还可以在类中使用,为类提供更好的复用性和灵活性。

class GenericNumber<T> {

zeroValue: T;

add: (x: T, y: T) => T;

}

let myGenericNumber = new GenericNumber<number>();

myGenericNumber.zeroValue = 0;

myGenericNumber.add = function(x, y) { return x + y; };

通过这种方式,我们可以创建一个通用的类 GenericNumber,它可以用于不同类型的数据操作,比如 numberstring,而不需要为每种数据类型重新定义类。

三、泛型工具类型

TypeScript 提供了一些内置的泛型工具类型,例如 PartialReadonlyRecordPick 等,这些都极大地便利了开发。

使用 Partial 工具类型

Partial 可以将某个类型里的属性全部变为可选的。这在处理大型接口或复杂类型时非常有用。

interface Todo {

title: string;

description: string;

}

function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>): Todo {

return { ...todo, ...fieldsToUpdate };

}

const todo1: Todo = { title: "organize desk", description: "clear clutter" };

const todo2 = updateTodo(todo1, { description: "throw out trash" });

使用 Readonly 工具类型

Readonly 可以使类型的所有属性变为只读,这有助于我们在需要保护某些对象不被改变时使用。

interface Todo {

title: string;

}

const todo: Readonly<Todo> = { title: "Delete inactive users" };

// todo.title = "Hello"; // Error: Cannot assign to 'title' because it is a read-only property.

通过这样的泛型工具类型,我们可以很容易地改进和扩展类型系统,提高代码的安全性和可维护性。泛型不只是一个高阶工具,它对于提升 TypeScript 的使用效率和代码质量有着不可或缺的作用。

相关问答FAQs:

什么是TypeScript中的泛型?

泛型允许我们在定义函数、类或接口时,使用不具体指定类型,而是在使用时再指定具体类型。这使得我们可以更灵活地编写可重用的代码。

如何在TypeScript中使用泛型?

在TypeScript中,我们可以使用<T>或者<T, U>等形式来表示泛型。在函数中,可以使用泛型代表参数类型、函数返回值类型或者数组类型。在类或接口中,泛型可以用来定义属性、方法或者函数参数的类型。

为什么要使用泛型?有什么好处?

泛型可以帮助我们编写更灵活、通用的代码,提高代码的复用性和灵活性。使用泛型可以减少代码重复,同时提高代码的可读性和维护性。泛型还可以在编译时进行类型检查,减少类型错误的发生,并提供更好的代码提示和自动补全功能。

相关文章