前端开发入门指南Day 17:TypeScript高级类型(泛型,类型守卫,Partial<T>和 Required<T>等)

泛型:代码的"变色龙" 🦎

为什么需要泛型?

想象一个快递员,每天要处理不同类型的包裹。如果为每种类型的包裹都写一套处理程序,那会很麻烦。泛型就像是一个"通用的包裹处理系统",它能智能地适应不同类型的包裹。

让我们通过一个简单的例子来理解:

// 没有泛型时,我们需要为每种类型写一个函数
function processNumberBox(box: { value: number }) {console.log(box.value + 10);
}function processStringBox(box: { value: string }) {console.log(box.value.toUpperCase());
}// 使用泛型后,一个函数就能处理所有类型
function processBox<T>(box: { value: T }) {console.log(box.value);return box.value;
}// 现在可以处理任何类型
processBox({ value: 42 });         // 处理数字
processBox({ value: "hello" });    // 处理字符串
processBox({ value: true });       // 处理布尔值

泛型就像"变量的变量" 📦

// 创建一个通用的"盒子"类
class Box<T> {private content: T;constructor(value: T) {this.content = value;}getValue(): T {return this.content;}
}// 创建不同类型的盒子
const numberBox = new Box(123);        // 数字盒子
const stringBox = new Box("hello");    // 字符串盒子
const dateBox = new Box(new Date());   // 日期盒子// TypeScript 会自动推断并确保类型安全
numberBox.getValue().toFixed(2);    // ✅ 可以,因为是数字
stringBox.getValue().toUpperCase(); // ✅ 可以,因为是字符串

实际应用场景 🎯

  1. 创建通用数据结构
// 创建一个通用的"盒子"类
class Box<T> {private content: T;constructor(value: T) {this.content = value;}getValue(): T {return this.content;}
}// 创建不同类型的盒子
const numberBox = new Box(123);        // 数字盒子
const stringBox = new Box("hello");    // 字符串盒子
const dateBox = new Box(new Date());   // 日期盒子// TypeScript 会自动推断并确保类型安全
numberBox.getValue().toFixed(2);    // ✅ 可以,因为是数字
stringBox.getValue().toUpperCase(); // ✅ 可以,因为是字符串
numberBox.getValue().toUpperCase(); // ❌ 错误!数字没有toUpperCase方法
  1. API响应处理
// 通用的API响应处理器
interface ApiResponse<T> {success: boolean;data: T;message: string;
}// 用户接口
interface User {id: number;name: string;
}// 使用泛型处理不同类型的响应
async function fetchUser(): Promise<ApiResponse<User>> {// ... API调用return {success: true,data: { id: 1, name: "张三" },message: "获取成功"};
}

类型守卫:代码的"安检员" 🚨

什么是类型守卫?

想象你是一个夜店保安,需要检查进入的人是否满足条件(年龄、着装等)。类型守卫就是代码世界的"保安",它帮助我们在运行时确保数据类型的正确性。

// 定义可能的类型
type Animal = Bird | Dog;interface Bird {type: "bird";flySpeed: number;
}interface Dog {type: "dog";runSpeed: number;
}// 类型守卫函数
function isBird(animal: Animal): animal is Bird {return animal.type === "bird";
}// 使用类型守卫
function moveAnimal(animal: Animal) {if (isBird(animal)) {// TypeScript现在知道这是一只鸟console.log(`飞行速度:${animal.flySpeed}`);} else {// TypeScript知道这是一只狗console.log(`奔跑速度:${animal.runSpeed}`);}
}

常见的类型守卫方式

  1. typeof 守卫
function process(value: string | number) {if (typeof value === "string") {// 这里TypeScript知道value是字符串return value.toUpperCase();} else {// 这里TypeScript知道value是数字return value.toFixed(2);}
}
  1. instanceof 守卫
class Car {drive() { console.log("开车"); }
}class Bicycle {ride() { console.log("骑行"); }
}function useVehicle(vehicle: Car | Bicycle) {if (vehicle instanceof Car) {vehicle.drive();} else {vehicle.ride();}
}

实用工具类型:代码的"瑞士军刀" 🛠️

TypeScript的工具类型也是这样的一个好用的工具集合:

1. Partial<T> - 所有属性变为可选

interface User {name: string;age: number;email: string;
}// 所有字段都变成可选的
type PartialUser = Partial<User>;
// 等同于:
// {
//    name?: string;
//    age?: number;
//    email?: string;
// }// 实际应用:更新用户信息
function updateUser(userId: number, updates: Partial<User>) {// 可以只更新部分字段
}

2. Required<T> - 所有属性变为必需

interface Config {name?: string;timeout?: number;
}// 所有字段都变成必需的
type RequiredConfig = Required<Config>;
// 等同于:
// {
//    name: string;
//    timeout: number;
// }

实际应用:创建表单验证规则

type ValidationRules<T> = {[K in keyof T]: {required?: boolean;minLength?: number;maxLength?: number;pattern?: RegExp;}
}// 使用
const employeeValidation: ValidationRules<Employee> = {name: { required: true, minLength: 2 },salary: { required: true, pattern: /^\d+$/ },department: { required: true }
};

映射类型:批量"加工"属性 🏭

想象你有一个印章,可以给所有属性都盖上"只读"的标记:

// 原始接口
interface Employee {name: string;salary: number;department: string;
}// 让所有属性只读
type ReadonlyEmployee = {readonly [K in keyof Employee]: Employee[K];
}// 让所有属性可选
type OptionalEmployee = {[K in keyof Employee]?: Employee[K];
}

这些高级类型特性看起来可能有点复杂,但它们就像乐高积木一样 - 一旦你理解了基本概念,就可以把它们组合起来构建更复杂的结构。这些特性的目的是帮助我们写出更安全、更可维护的代码。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LRU Cache替换算法

目录 1.什么是LRU Cache&#xff1f; 2.LRU Cache 的底层结构 3.LRU Cache的实现 LRUCache类中的接口总览 构造函数 get操作 put操作 打印 4.LRU Cache的测试 5.LRU Cache相关OJ题 6.LRU Cache类代码附录 1.什么是LRU Cache&#xff1f; 首先我想解释一下什么是cach…

小米二面:JVM 触发类加载的条件有哪些?

类加载生命周期 类加载的生命周期包括&#xff1a;加载&#xff08;Loading&#xff09;、链接&#xff08;Linking&#xff09; 和 初始化&#xff08;Initialization&#xff09;。而其中&#xff0c;初始化阶段是决定类是否被真正加载的关键。 JVM 在什么时候启动类加载过…

数字孪生与大型模型强强联合,共塑工业制造崭新前景

随着新一代信息技术与实体经济的加速融合&#xff0c;工业领域的数字化、智能化转型趋势愈发显著&#xff0c;孕育出一系列制造业数字化转型的新模式与新业态。在此背景下&#xff0c;数字孪生技术作为关键支撑力量&#xff0c;正在全球范围内迅速崛起并得到广泛应用&#xff0…

【笔记2-5】ESP32:freertos消息队列

主要参考b站宸芯IOT老师的视频&#xff0c;记录自己的笔记&#xff0c;老师讲的主要是linux环境&#xff0c;但配置过程实在太多问题&#xff0c;就直接用windows环境了&#xff0c;老师也有讲一些windows的操作&#xff0c;只要代码会写&#xff0c;操作都还好&#xff0c;开发…

Qt Chart 模块化封装曲线图

一 版本说明 二 完成示例 此文章包含:曲线轴设置,曲线切换,单条曲线显示,坐标轴。。。 三 曲线图UI创建 在UI界面拖放一个QWidget,然后在 Widget里面放一个 graphicsView 四 代码介绍 1 头文件 #include <QString> #include <QTimer> #include <QMessa…

a7678 食品添加剂健康小助手系统微信小程序的的设计与实现 后台php+mysql+layui+thinkphp 源码 配置 文档 全套资料

食品添加剂健康小助手 1.摘要2.开发目的和意义3.系统功能设计4.系统界面截图5.源码获取 1.摘要 食品添加剂健康小助手系统是一个能够帮助消费者更好地了解食品添加剂相关信息的智能系统。在现代食品生产过程中&#xff0c;许多食品添加剂被广泛使用&#xff0c;以提高食品的质…

HTTP(超文本传输协议)

HTTP是万维网通信的基础构成&#xff0c;是一个简单的请求相应协议&#xff0c;基于TCP之上80号端口 通信原理 DNS解析 将域名甩个DNS服务器解析&#xff0c;将域名化为IP访问 建立TCP连接 如图&#xff0c;客户端先发送一个sys置位seq为x&#xff08;任意值&#xff09;的…

如何设置合理的爬取频率避免被网站封锁?

要合理设置爬取频率以避免被网站封锁&#xff0c;可以采取以下几种策略&#xff1a; 遵守robots.txt规范&#xff1a;确保爬虫程序遵守目标网站的robots.txt文件中定义的爬取规则&#xff0c;避免爬取被网站禁止的内容。 设置请求头信息&#xff1a;在爬取时&#xff0c;设置合…

LeetCode Hot100 51~60

图论51. 岛屿问题52. 腐烂的橘子53. 课程表54. 前缀树55. 全排列56. 子集57. 电话号码58. 组合总和59. 括号生成60. 单词搜索 图论 51. 岛屿问题 经典洪水问题算法 class Solution { public:int numIslands(vector<vector<char>>& grid) {int nr grid.size…

SpringBoot的validation参数校验

文章目录 前言一、引入validation 依赖二、validation中的注解说明 &#xff08;1&#xff09;Validated&#xff08;2&#xff09;Valid&#xff08;3&#xff09;NotNull&#xff08;4&#xff09;NotBlank&#xff08;5&#xff09;NotEmpty&#xff08;6&#xff09;Patte…

SSH克隆github项目

1、生成密钥 ssh-keygen -t rsa -C "你的邮箱xxx.com" 全程回车即可&#xff08;不用输入ras文件名及密码&#xff09;、为了方便下面的公钥查看 2、配置公钥 查看公钥内容 cat c:\Users\xxx\.ssh\id_rsa.pub(修改为自己的路径及名字) 将公钥内容复制并粘贴至…

CASAIM与中国航天携手合作,CASAIM IS全自动化光学测量系统交付中国航天山西工厂,助力航空航天零部件全自动化3D测量

近日&#xff0c;CASAIM与中国航天达成全自动化光学测量技术合作&#xff0c;并将CASAIM IS全自动化光学测量系统交付给中国航天科技集团山西工厂&#xff0c;这一合作标志着双方在智能制造和精密测量领域迈出了重要一步。 中国航天科技&#xff0c;是在中国战略高技术领域拥有…

基于Springboot+Vue的电子博物馆系统

基于SpringbootVue的电子博物馆系统 前言&#xff1a;随着信息技术的不断发展&#xff0c;传统博物馆的参观方式逐渐向数字化、在线化转型。电子博物馆作为这一转型的重要组成部分&#xff0c;能够通过信息化手段为用户提供更丰富、更便捷的博物馆参观体验。本文基于Spring Boo…

【软考速通笔记】系统架构设计师⑭——面向服务架构设计理论与实践

文章目录 一、前言二、基础知识2.1 介绍2.2 作用 三、参考架构四、主要协议五、设计原则六、设计模式6.1 服务注册模式6.2 企业服务总线模式6.3 微服务模式6.4 微服务架构模式方案 七、注意事项 一、前言 笔记目录大纲请查阅&#xff1a;【软考速通笔记】系统架构设计师——导读…

K8S的资源配置

资源配额 当多个用户或团队共享具有固定节点数目的集群时&#xff0c;人们会担心有人使用超过其基于公平原则所分配到的资源量。资源配额是帮助管理员解决这一问题的工具。资源配额&#xff0c;通过 ResourceQuota 对象来定义&#xff0c;对每个命名空间的资源消耗总量提供限制…

Python+OpenCV系列:入门环境搭建、图像读写、像素操作、色彩空间和通道、

入门环境搭建、图像读写、像素操作、色彩空间和通道 **Python与OpenCV环境搭建、图像处理与色彩空间介绍****引言****1. Python和OpenCV的环境搭建****1.1 安装Python和OpenCV****1.2 配置开发环境** **2. 图像的读取、显示与保存****2.1 图像的读取****2.2 图像的显示****2.3 …

在Docker中部署禅道,亲测可用

1、确保centos中已安装docker docker -v 2、启动docker systemctl start docker 3、可设置docker开机启动 systemctl enable docker.service 4、获取最新版禅道开源版镜像 docker pull idoop/zentao 5、运行镜像生成禅道容器【创建 /data/www /data/data 目录】 doc…

vitepress组件库文档项目 markdown语法大全(修正版)

#上次总结的 有些语法是用在markdown文档中的 使用到vitepress项目中有些语法可能有出入 于是我再总结一版 vitepress项目中的markdown语法大全 在阅读本章节之前&#xff0c;请确保你已经对 Markdown 有所了解。如果你还不了解 Markdown &#xff0c;请先学习一些Markdown 教…

String IP和Int IP的互相转换

android中&#xff0c;wifiManager.connectionInfo.ipAddress 可以获取到wifi的ip地址&#xff0c;但这是一个int值&#xff0c;如何转换为常见的如192.168.1.129这种形式&#xff0c;以及这种形式如何转换回int值的形式。 这里ip分为4段&#xff0c;每一段的值都是0 ~ 255&am…

Blender导入下载好的fbx模型像的骨骼像针戳/像刺猬

为什么我下载下来的骨骼模型和我自己绑定的模型骨骼朝向完全不一样 左边是下载的模型 右边是我自己绑定的模型 左边的模型刚刚感觉都是像针一样往外戳的&#xff0c;像刺猬一样那种。 解决方法勾选自动骨骼坐标系