当前位置: 首页 > news >正文

前端开发入门指南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];
}

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

相关文章:

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

泛型&#xff1a;代码的"变色龙" &#x1f98e; 为什么需要泛型&#xff1f; 想象一个快递员&#xff0c;每天要处理不同类型的包裹。如果为每种类型的包裹都写一套处理程序&#xff0c;那会很麻烦。泛型就像是一个"通用的包裹处理系统"&#xff0c;它能…...

flex布局容易忽略的角色作用

目录 清除浮动 作用于行内元素 flex-basis宽度 案例一&#xff1a; 案例二&#xff1a; 案例三&#xff1a; flex-grow设置权重 案例一&#xff1a; 案例二&#xff1a; 简写flex-grow:1 0 auto; flex作为一维布局,行和列的使用&#xff0c;忽略的小角色&#xff0c;大…...

如何开发高效的企业内训APP?教育培训系统源码搭建实战详解

本篇文章&#xff0c;小编将从教育培训系统的源码搭建、功能设计以及技术实现等方面&#xff0c;详细探讨如何开发一款高效的企业内训APP。 一、企业内训APP的需求分析 在开发企业内训APP之前&#xff0c;首先需要明确其基本需求。一个高效的企业内训APP应该具备以下几个核心…...

【软考网工笔记】网络基础理论——传输层

IPSec协议 Internet协议安全性是一种开放标准的框架结构&#xff0c;通过使用加密的安全服务以确保在Internet协议&#xff08;IP&#xff09;网络上进行保密而安全的通讯。 工作在OSI模型的第三层网络层上&#xff0c;使其在单独使用时适于保护基于TCP或UDP的协议&#xff0…...

如何预防服务器后台爆破攻击

服务器后台爆破&#xff08;Brute Force Attack&#xff09;是一种通过反复尝试用户名和密码组合&#xff0c;以非法获取系统访问权限的攻击方式。这种攻击不仅会消耗服务器资源&#xff0c;还可能导致合法用户被锁定或敏感数据泄露。为了有效预防服务器后台爆破攻击&#xff0…...

CMake笔记之在CMakeLists.txt文件中开启Debug模式

CMake笔记之在CMakeLists.txt文件中开启Debug模式 code review! 文章目录 CMake笔记之在CMakeLists.txt文件中开启Debug模式1.设置 CMake 的构建类型2.添加编译器的调试选项3.使用 CMAKE_CXX_STANDARD (可选)4.编译和构建5.针对多配置生成器6.最终示例 CMakeLists.txt 1.设置 …...

C++编程:模拟实现CyberRT的DataVisitor和DataDispatcher

文章目录 0. 引言1. 设计概要1.1 主要组件1.2 类关系图1.3 工作流程 2. 代码实现2.1. 定义数据结构2.2. 实现 DataVisitor2.3. 实现 DataDispatcher2.4. 实现 Receiver2.5. 实现具体的 DataVisitor2.6. 示例主程序2.7. 编译和运行 0. 引言 使用 C 实现一个类似CyberRT 架构的 …...

【Flutter】WillPopScope组件-监听物理返回键事件自定义返回事件

WillPopScope(onWillPop: () async {if ( flutterWebViewPlugin ! null && await flutterWebViewPlugin.canGoBack() true) {flutterWebViewPlugin!.goBack();return false; // 阻止默认的返回行为} else {return true; // 允许默认的返回行为}},child: Scaffold(),);…...

【sqlserver】mssql 批量加载数据文件 bulk copy使用

参考文章&#xff1a; Using bulk copy with the JDBC driver SqlServer数据批量写入 SqlServer批量插入数据方法–SqlBulkCopy sqlserver buld copy需要提供&#xff0c;数据文件的对应表的元数据信息主要的字段的位置、字段的名称、字段的数据类型。 执行bulk load时候不一…...

flinkSql中累计窗口CUMULATE

eventTime package com.bigdata.day08;import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;public class _05_flinkSql_Cumulate_eventTime {/*** 累积窗口 eventTime* …...

关于在ubuntu上无法运行EasyConnect的解决方法

需要这三个文件 libpangocairo-1.0-0_1.40.14-1_amd64.deb libpangoft2-1.0-0_1.40.14-1_amd64.deb libpango-1.0-0_1.40.14-1_amd64.deb然后执行 cp source /usr/share/sangfor/EasyConnect再重启EasyConnect即可 下载链接 http://kr.archive.ubuntu.com/ubuntu/pool/main/…...

【Axure高保真原型】数值条件分组

今天和大家分享数值条件分组的原型模板&#xff0c;效果包括&#xff1a; 点击添加分组按钮&#xff0c;可以显示添加弹窗&#xff0c;填写分组名称和数值区间后&#xff0c;可以新增该分组信息‘’ 修改分组区间&#xff0c;可以直接在输入框里修改已有的分组区间&#xff0c…...

python学习——字符串的拼接操作

在Python中&#xff0c;字符串拼接是一项基本操作&#xff0c;用于将多个字符串合并成一个字符串。以下是几种常见的字符串拼接方式&#xff1a; 1. 使用 运算符 最简单和直接的方式是使用 运算符来拼接字符串。 str1 "Hello, " str2 "World!" resu…...

多线程篇-8--线程安全(死锁,常用保障安全的方法,安全容器,原子类,Fork/Join框架等)

1、线程安全和不安全定义 &#xff08;1&#xff09;、线程安全 线程安全是指一个类或方法在被多个线程访问的情况下可以正确得到结果&#xff0c;不会出现数据不一致或其他错误行为。 线程安全的条件 1、原子性&#xff08;Atomicity&#xff09; 多个操作要么全部完成&a…...

el-select的搜索功能

el-select的相关信息&#xff1a; 最基本信息 v-model的值为当前被选中的el-option的 value 属性值 :label是选择器可以看到的内容 过滤搜索 普通过滤搜索 <el-selectv-model"selectedCountry"placeholder"请选择国家"filterable:loading"lo…...

MFC实现全屏功能

之前全屏都是参考&#xff1a; MFC单文档&#xff08;SDI&#xff09;全屏程序的实现 主要思路就是将各种菜单工具栏隐藏恢复。 随着MFC的升级&#xff0c;MFC框架本身就具备了全屏的功能。 微软有一个全屏实现类&#xff1a; CFullScreenImpl Class managing full-screen mod…...

网络安全技术详解:虚拟专用网络(VPN) 安全信息与事件管理(SIEM)

虚拟专用网络&#xff08;VPN&#xff09;详细介绍 虚拟专用网络&#xff08;VPN&#xff09;通过在公共网络上创建加密连接来保护数据传输的安全性和隐私性。 工作原理 VPN的工作原理涉及建立安全隧道和数据加密&#xff1a; 隧道协议&#xff1a;使用协议如PPTP、L2TP/IP…...

v-model 根据后端接口返回的数据动态地确定要绑定的变量

在 Vue 中&#xff0c;v-model 是用于创建双向绑定的指令。通常&#xff0c;它用于与组件或表单元素的值进行绑定。但有时你可能需要根据后端接口返回的数据动态地确定要绑定的变量。 你可以通过以下步骤来实现这个需求&#xff1a; 步骤 1: 获取后端接口数据 首先&#xff…...

图形开发基础之在WinForms中使用OpenTK.GLControl进行图形绘制

前言 GLControl 是 OpenTK 库中一个重要的控件&#xff0c;专门用于在 Windows Forms 应用程序中集成 OpenGL 图形渲染。通过 GLControl&#xff0c;可以轻松地将 OpenGL 的高性能图形绘制功能嵌入到传统的桌面应用程序中。 1. GLControl 的核心功能 OpenGL 渲染上下文&…...

离散数学重点复习

第一章.集合论 概念 1.集合是不能精确定义的基本数学概念.通常是由指定范围内的满足给定条件的所有对象聚集在一起构成的 2.制定范围内的每一个对象称为这个集合的元素 3.固定符号如下: N:自然数集合 Z:整数集合 Q:有理数集合 R:实数集合 C:复数集合 4.集合中的元素是…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

热烈祝贺埃文科技正式加入可信数据空间发展联盟

2025年4月29日&#xff0c;在福州举办的第八届数字中国建设峰会“可信数据空间分论坛”上&#xff0c;可信数据空间发展联盟正式宣告成立。国家数据局党组书记、局长刘烈宏出席并致辞&#xff0c;强调该联盟是推进全国一体化数据市场建设的关键抓手。 郑州埃文科技有限公司&am…...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践

前言&#xff1a;本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中&#xff0c;跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南&#xff0c;你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案&#xff0c;并结合内网…...