对 TypeScript 中泛型如何更好的理解?都有那些应用场景?

TypeScript 中泛型的理解与应用

泛型 (Generics) 是 TypeScript 的强大特性之一,允许我们在定义函数、类、接口等时,使用类型参数来使得代码更加灵活和可重用。泛型通过延迟指定类型的方式,使得代码在不失去类型检查的前提下,可以处理多种不同类型的数据。

1. 泛型的基本概念

泛型使得函数、类、接口等的类型能够在使用时灵活指定,而不是提前硬编码某种类型。这使得我们的代码更加灵活且类型安全。

示例:基本的泛型函数
function identity<T>(arg: T): T {
    return arg;
}

let result1 = identity(5);         // result1 的类型是 number
let result2 = identity("hello");   // result2 的类型是 string

在这个例子中,identity 函数接受一个类型参数 T,并返回同样类型的值。T 代表一个占位符,表示我们将来可以传递任何类型给函数,函数会自动推断出返回值的类型。

2. 泛型的应用场景

1. 通用函数

泛型函数通常用于处理不同类型的数据,但又不希望在每次调用时都明确指定类型。通过泛型,我们可以为函数提供更强的类型安全性。

2. 容器类(集合类型)

泛型在容器类中尤为重要。例如,我们可以定义一个数组类,允许数组中的元素是任何类型。

3. 类型约束

泛型可以配合类型约束,限制泛型的具体类型,使得代码在灵活性和安全性之间取得平衡。

4. 接口和类

泛型不仅可以应用于函数,还可以应用于接口和类,进一步增强代码的复用性和类型安全性。

3. 泛型的实际项目应用

示例 1:泛型数组

假设你在开发一个库存管理系统,可能会有多个不同类型的库存项目,如书籍、电子产品、家具等。我们可以使用泛型来创建一个通用的数组管理工具,使其能够管理不同类型的库存项目。

class Inventory<T> {
    private items: T[] = [];

    add(item: T): void {
        this.items.push(item);
    }

    getAll(): T[] {
        return this.items;
    }
}

interface Book {
    title: string;
    author: string;
}

interface Electronics {
    name: string;
    brand: string;
    warrantyPeriod: number;
}

// 使用泛型数组管理书籍
let bookInventory = new Inventory<Book>();
bookInventory.add({ title: "The Catcher in the Rye", author: "J.D. Salinger" });
bookInventory.add({ title: "1984", author: "George Orwell" });

console.log(bookInventory.getAll());  // 输出书籍的数组

// 使用泛型数组管理电子产品
let electronicsInventory = new Inventory<Electronics>();
electronicsInventory.add({ name: "Smartphone", brand: "BrandX", warrantyPeriod: 2 });
electronicsInventory.add({ name: "Laptop", brand: "BrandY", warrantyPeriod: 3 });

console.log(electronicsInventory.getAll());  // 输出电子产品的数组

在这个示例中,Inventory 类是一个泛型类,它可以管理任何类型的库存项目。通过使用泛型,我们能够实现一个通用的库存管理工具,而不需要为每种类型的库存单独定义一个类。

示例 2:泛型接口

泛型接口可以用于定义通用的数据结构,例如在开发一个 API 客户端时,我们可能需要一个接口来处理不同类型的响应数据。

interface ApiResponse<T> {
    data: T;
    status: string;
    message: string;
}

function handleApiResponse<T>(response: ApiResponse<T>) {
    console.log(`Status: ${response.status}`);
    console.log(`Message: ${response.message}`);
    console.log("Data:", response.data);
}

interface User {
    id: number;
    name: string;
}

interface Product {
    id: number;
    name: string;
    price: number;
}

// 使用泛型接口处理不同的 API 响应
const userResponse: ApiResponse<User> = {
    data: { id: 1, name: "Alice" },
    status: "success",
    message: "User fetched successfully"
};

handleApiResponse(userResponse);

const productResponse: ApiResponse<Product> = {
    data: { id: 101, name: "Laptop", price: 1500 },
    status: "success",
    message: "Product fetched successfully"
};

handleApiResponse(productResponse);

在这个示例中,ApiResponse<T> 是一个泛型接口,用来描述 API 响应的数据结构。通过泛型参数 T,我们能够根据不同的响应类型灵活调整数据结构。

示例 3:泛型约束

有时我们希望对泛型进行约束,确保其具有某些特定的属性或方法。可以使用 extends 关键字来约束泛型类型。

interface Nameable {
    name: string;
}

function printName<T extends Nameable>(item: T): void {
    console.log(item.name);
}

const person = { name: "Alice", age: 25 };
const product = { name: "Laptop", price: 1000 };

// 这两个对象都符合 Nameable 的约束
printName(person);  // 输出 "Alice"
printName(product);  // 输出 "Laptop"

// 下面的代码会报错,因为没有 name 属性
// const invalidObject = { age: 25 };
// printName(invalidObject);  // 编译错误

在这个例子中,T extends Nameable 表示泛型 T 必须具有 name 属性。这样可以确保我们只能传递那些符合条件的数据类型,增强了类型安全性。

4. 泛型的高级应用

1. 联合类型与泛型

泛型和联合类型结合使用,可以允许函数处理多种类型的输入。

function combine<T, U>(a: T, b: U): T | U {
    return a || b;
}

let result = combine(5, "hello");
console.log(result);  // 输出 "hello"
2. 条件类型

TypeScript 4.1 引入了条件类型,它允许根据条件来决定类型。

type IsString<T> = T extends string ? "Yes" : "No";

type A = IsString<string>;  // "Yes"
type B = IsString<number>;  // "No"

5. 总结

泛型 是 TypeScript 中的一个强大工具,它可以使得代码更加灵活、类型安全并且可重用。通过泛型,函数、类、接口等结构可以处理不同类型的数据,而不牺牲类型检查的安全性。常见的应用场景包括:

  • 通用的数据结构或容器类,如数组、列表等。
  • 高度可重用的函数和 API 请求处理。
  • 通过类型约束限制泛型的使用,使得代码既灵活又安全。

通过实际项目中的应用示例,我们可以看到泛型在项目中的重要性,它使得代码更加模块化、可扩展,并且减少了重复代码的编写。

希望这些例子和讲解能帮助你深入理解 TypeScript 中的泛型及其应用场景!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921583.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode 3244.新增道路查询后的最短距离 II:贪心(跃迁合并)-9行py(O(n))

【LetMeFly】3244.新增道路查询后的最短距离 II&#xff1a;贪心&#xff08;跃迁合并&#xff09;-9行py&#xff08;O(n)&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/shortest-distance-after-road-addition-queries-ii/ 给你一个整数 n 和一个二维…

华为无线AC+AP组网实际应用小结

之前公司都是使用的H3C的交换机、防火墙以及无线AC和AP的&#xff0c;最近优化下无线网络&#xff0c;说新的设备用华为的&#xff0c;然后我是直到要部署的当天才知道用华为设备的&#xff0c;就很无语了&#xff0c;一点准备没有&#xff0c;以下为这次的实际操作记录吧&…

Fakelocation Server服务器/专业版 Windows11

前言:需要Windows11系统 Fakelocation开源文件系统需求 Windows11 | Fakelocation | 任务一 打开 PowerShell&#xff08;以管理员身份&#xff09;命令安装 Chocolatey Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProto…

C语言基础学习:抽象数据类型(ADT)

基础概念 抽象数据类型&#xff08;ADT&#xff09;是一种数据类型&#xff0c;它定义了一组数据以及可以在这组数据上执行的操作&#xff0c;但隐藏了数据的具体存储方式和实现细节。在C语言中&#xff0c;抽象数据类型&#xff08;ADT&#xff09;是一种非常重要的概念&…

基于深度学习CNN算法的花卉分类识别系统01--带数据集-pyqt5UI界面-全套源码

文章目录 基于深度学习算法的花卉分类识别系统一、项目摘要二、项目运行效果三、项目文件介绍四、项目环境配置1、项目环境库2、环境配置视频教程 五、项目系统架构六、项目构建流程1、数据集2、算法网络Mobilenet3、网络模型训练4、训练好的模型预测5、UI界面设计-pyqt56、项目…

Bokeh实现大规模数据可视化的最佳实践

目录 引言 一、Bokeh简介 二、安装Bokeh 三、数据准备 四、性能优化 五、创建图表 六、添加交互功能 七、应用案例 八、高级技巧 九、总结 引言 在数据科学领域,数据可视化是一个至关重要的环节。通过可视化,我们可以直观地理解数据的特征和趋势,为数据分析和决策…

Easyexcel(4-模板文件)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09; 文件导出 获取 resources 目录下的文件&#xff0c;使用 withTemplate 获…

【山大909算法题】2014-T1

文章目录 1.原题2.算法思想3.关键代码4.完整代码5.运行结果 1.原题 为带表头的单链表类Chain编写一个成员函数Reverse&#xff0c;该函数对链表进行逆序操作&#xff08;将链表中的结点按与原序相反的顺序连接&#xff09;&#xff0c;要求逆序操作就地进行&#xff0c;不分配…

[Redis#2] 定义 | 使用场景 | 安装教程 | 快!

目录 1. 定义 In-memory data structures 在内存中存储数据 2. 优点&#xff01;快 Programmability 可编程性 Extensibility 扩展性 Persistence 持久化 Clustering 分布式集群 High availability 高可用性 ⭕快速访问的实现 3. 使用场景 1.Real-time data store …

学习编程,学习中间件,学习源码的思路

01 看的多&#xff0c;内化不足 最近想复习一下编程相关的知识&#xff0c;在复习前我翻开了之前的一些笔记&#xff0c;这些笔记基本都是从书本、视频、博客等摘取记录的&#xff0c;看着这些笔记心里总结&#xff1a;看的多&#xff0c;内化不足。 02 整理大纲 为了解决这个…

hhdb数据库介绍(10-2)

集群管理 计算节点集群 集群管理主要为用户提供对计算节点集群的部署、添加、启停监控、删除等管理操作。 集群管理记录 集群管理页面显示已部署或已添加的计算节点集群信息。可以通过左上角搜索框模糊搜索计算节点集群名称进行快速查找。同时也可以通过右侧展开展开/隐藏更…

AG32既可以做MCU,也可以仅当CPLD使用

Question: AHB总线上的所有外设都需要像ADC一样&#xff0c;通过cpld处理之后才能使用? Reply: 不用。 除了ADC外&#xff0c;其他都是 mcu可以直接配置使用的。 Question: DMA和CMP也不用? Reply: DMA不用。 ADC/DAC/CMP 用。 CMP 其实配置好后&#xff0c;可以直…

贪心算法(1)

目录 柠檬水找零 题解&#xff1a; 代码&#xff1a; 将数组和减半的最少操作次数&#xff08;大根堆&#xff09; 题解&#xff1a; 代码&#xff1a; 最大数&#xff08;注意 sort 中 cmp 的写法&#xff09; 题解&#xff1a; 代码&#xff1a; 摆动序列&#xff0…

网络爬虫——综合实战项目:多平台房源信息采集与分析系统

1. 项目背景与目标 1.1 项目背景 随着房产市场的快速发展&#xff0c;各大平台上充斥着大量房源信息。为了帮助用户快速掌握市场动态&#xff0c;需要通过爬虫技术自动采集多平台数据&#xff0c;清洗后进行存储和分析&#xff0c;为用户提供有价值的洞察。开发者通过这一实战…

数据结构-7.Java. 对象的比较

本篇博客给大家带来的是java对象的比较的知识点, 其中包括 用户自定义类型比较, PriorityQueue的比较方式, 三种比较方法...... 文章专栏: Java-数据结构 若有问题 评论区见 欢迎大家点赞 评论 收藏 分享 如果你不知道分享给谁,那就分享给薯条. 你们的支持是我不断创作的动力 .…

NVR录像机汇聚管理EasyNVR多品牌NVR管理工具/设备如何使用Docker运行?

在当今的安防监控领域&#xff0c;随着视频监控技术的不断发展和应用范围的扩大&#xff0c;如何高效、稳定地管理并分发视频流资源成为了行业内外关注的焦点。EasyNVR作为一款功能强大的多品牌NVR管理工具/设备&#xff0c;凭借其灵活的部署方式和卓越的性能&#xff0c;正在引…

LSTM原理解读与实战

在RNN详解及其实战中&#xff0c;简单讨论了为什么需要RNN这类模型、RNN的具体思路、RNN的简单实现等问题。同时&#xff0c;在文章结尾部分我们提到了RNN存在的梯度消失问题&#xff0c;及之后的一个解决方案&#xff1a;LSTM。因此&#xff0c;本篇文章主要结构如下&#xff…

Springboot之登录模块探索(含Token,验证码,网络安全等知识)

简介 登录模块很简单&#xff0c;前端发送账号密码的表单&#xff0c;后端接收验证后即可~ 淦&#xff01;可是我想多了&#xff0c;于是有了以下几个问题&#xff08;里面还包含网络安全问题&#xff09;&#xff1a; 1.登录时的验证码 2.自动登录的实现 3.怎么维护前后端…

使用Element UI实现前端分页,前端搜索,及el-table表格跨页选择数据,切换分页保留分页数据,限制多选数量

文章目录 一、前端分页1、模板部分 (\<template>)2、数据部分 (data)3、计算属性 (computed)4、方法 (methods) 二、前端搜索1、模板部分 (\<template>)2、数据部分 (data)3、计算属性 (computed)4、方法 (methods) 三、跨页选择1、模板部分 (\<template>)2、…

VMware Workstation 17.6.1

概述 目前 VMware Workstation Pro 发布了最新版 v17.6.1&#xff1a; 本月11号官宣&#xff1a;针对所有人免费提供&#xff0c;包括商业、教育和个人用户。 使用说明 软件安装 获取安装包后&#xff0c;双击默认安装即可&#xff1a; 一路单击下一步按钮&#xff1a; 等待…