联合类型的逻辑或关系与类型保护
在 TypeScript 中,联合类型(Union Types)是一种强大的类型工具,它允许一个变量可以是几种不同类型中的一种。联合类型通过逻辑“或”关系(|
)连接多个类型。这种类型的灵活性使得我们能够处理多样化的数据输入和返回类型。然而,由于联合类型的变量在不同的使用场景中可能是不同的类型,我们需要采用类型保护(Type Guards)来确保代码的类型安全。
本文将深入探讨联合类型的逻辑“或”关系以及如何使用类型保护来有效地处理联合类型。
1. 联合类型的逻辑或关系
联合类型通过逻辑“或”关系(|
)将多个类型组合在一起。例如,当你定义一个变量时,你希望它可以是字符串或数字,那么可以使用联合类型来定义
type StringOrNumber = string | number;let value: StringOrNumber;
value = "Hello, TypeScript"; // 合法
value = 42; // 合法
value = true; // 错误,布尔类型不是联合类型的一部分
在上述代码中,value
可以是字符串 (string
) 或数字 (number
) 类型。联合类型表示的“或”关系意味着变量的值可以是多种类型之一。你可以使用联合类型来表示很多类似的情形,例如:
- 一个输入框的值可以是字符串或数字。
- 一个 API 响应可能返回成功(字符串)或错误(数字)代码。
2. 联合类型和类型保护
虽然联合类型非常灵活,但它们的多样性也带来了挑战,特别是在运行时如何根据实际类型做出正确的处理。为了保证代码的安全性和正确性,我们需要使用类型保护(Type Guards)来判断一个变量的具体类型。类型保护帮助 TypeScript 在特定的代码块中“细化”类型,从而提高类型推断的准确性。
3. 类型保护的常见方法
3.1 使用 typeof
进行类型保护
typeof
是 TypeScript 提供的一个关键字,用于检查一个变量的基本类型。在联合类型中,我们可以通过 typeof
来判断变量的实际类型,从而进行相应的处理。
type StringOrNumber = string | number;function handleValue(value: StringOrNumber) {if (typeof value === "string") {// 类型被细化为 stringconsole.log(`It's a string: ${value}`);} else {// 类型被细化为 numberconsole.log(`It's a number: ${value}`);}
}handleValue("Hello, World!"); // 输出: It's a string: Hello, World!
handleValue(123); // 输出: It's a number: 123
在上面的例子中,我们通过 typeof value === "string"
来判断 value
是否为字符串类型。如果是,则 value
的类型会被 TypeScript 自动细化为 string
,此时我们可以安全地使用字符串相关的方法和属性。如果不是字符串,则可以推断它是数字类型,从而进行数字处理。
3.2 使用 instanceof
进行类型保护
instanceof
是另一个常见的类型保护工具,通常用于检查一个对象是否为某个类的实例。当联合类型中包含类类型时,instanceof
可以帮助我们区分不同的类实例。
class Dog {bark() {console.log("Woof!");}
}class Cat {meow() {console.log("Meow!");}
}type Animal = Dog | Cat;function makeNoise(animal: Animal) {if (animal instanceof Dog) {animal.bark(); // 类型被细化为 Dog} else {animal.meow(); // 类型被细化为 Cat}
}const dog = new Dog();
const cat = new Cat();makeNoise(dog); // 输出: Woof!
makeNoise(cat); // 输出: Meow!
在这个例子中,animal instanceof Dog
和 animal instanceof Cat
用来判断 animal
是 Dog
还是 Cat
的实例。根据不同的类型,TypeScript 会自动细化变量的类型,使我们能够安全地调用特定类的方法。
3.3 自定义类型保护
除了 typeof
和 instanceof
,你还可以定义自己的类型保护函数。自定义类型保护通过返回一个布尔值,并且在返回 true
时使用 is
关键字来缩小类型范围。
type StringOrNumber = string | number;function isString(value: StringOrNumber): value is string {return typeof value === "string";
}function printValue(value: StringOrNumber) {if (isString(value)) {console.log(`String: ${value}`);} else {console.log(`Number: ${value}`);}
}printValue("Hello"); // 输出: String: Hello
printValue(123); // 输出: Number: 123
在这个例子中,isString
是一个自定义的类型保护函数。当 isString(value)
返回 true
时,TypeScript 会知道 value
必定是 string
类型,因此后续代码中对 value
的使用将只限于字符串类型的操作。
4. 联合类型的复杂场景
联合类型常常与其他类型(如交叉类型、数组类型等)结合使用,构建更为复杂的数据结构。我们同样可以在这些复杂类型中使用类型保护。
4.1 联合类型与交叉类型的结合
type A = { name: string };
type B = { age: number };
type C = A & B; // C 是 A 和 B 的交叉类型type Person = C | string; // Person 既可以是 C 类型,也可以是 string 类型function describe(person: Person) {if (typeof person === "string") {console.log(`It's a string: ${person}`);} else {console.log(`Name: ${person.name}, Age: ${person.age}`);}
}describe("John Doe"); // 输出: It's a string: John Doe
describe({ name: "Jane", age: 30 }); // 输出: Name: Jane, Age: 30
在这个例子中,Person
类型是一个联合类型,它可以是一个字符串,也可以是一个包含 name
和 age
属性的对象。通过类型保护,我们能够安全地处理这两种类型。
5. 总结
联合类型是 TypeScript 中一种非常有用的类型工具,允许一个变量可以是多个类型中的一个。通过使用逻辑“或”关系(|
),我们能够灵活地处理多种数据类型。然而,由于联合类型的多样性,我们需要使用类型保护来确保代码的类型安全。
常见的类型保护手段包括使用 typeof
、instanceof
以及自定义类型保护函数。它们帮助 TypeScript 根据实际值的类型来细化变量的类型,从而避免错误的类型操作,提升代码的可维护性和类型安全性。
通过合理使用联合类型和类型保护,我们能够构建更加健壮和灵活的 TypeScript 应用程序。
希望这篇博客对你有所帮助!如果有任何问题或建议,欢迎留言讨论。
相关文章:
联合类型的逻辑或关系与类型保护
在 TypeScript 中,联合类型(Union Types)是一种强大的类型工具,它允许一个变量可以是几种不同类型中的一种。联合类型通过逻辑“或”关系(|)连接多个类型。这种类型的灵活性使得我们能够处理多样化的数据输…...
spring boot3.0自定义校验注解:文章状态校验示例
文章目录 Spring Boot 自定义校验注解:状态校验示例一、创建 State 注解步骤:1. 创建自定义注解:2. 实现校验逻辑: 二、 实现自定义校验步骤:1. 在实体类中使用自定义校验注解 State:2. 添加 State 注解: 总…...
神经网络是如何工作的
人工智能最核心的技术之一,就是神经网络(Neural Networks)。但很多初学者会觉得它是个黑盒:为什么神经网络能识别图片、翻译语言,甚至生成文章? 本文用图解最小代码实现的方式,带你深入理解&am…...

【工作记录】crmeb后端项目打开、运行
1、下载代码 1)安装git 不再详述 2)git拉代码 项目地址如下,在vscode-分支中拉代码 # 克隆项目 git clone https://gitee.com/ZhongBangKeJi/crmeb_java/ 截图如下是已经成功拉下来 注意安装对应版本 2、maven配置 安装配置见&#x…...

智能手表测试计划文档(软/硬件)
📄 智能手表测试计划文档(软/硬件) 项目名称:Aurora Watch S1 文档编号:AW-S1-QA-TP-001 编制日期:2025-xx-xx 版本:V1.0 编写人:xxx(测试主管) 一、测试目标…...
DeepSeek:开启能源领域智能化变革新时代
目录 一、DeepSeek 与能源领域变革的邂逅1.1 DeepSeek 在人工智能领域的地位与特点1.2 能源行业面临的挑战与变革需求1.3 DeepSeek 在能源领域应用的重要性和意义 二、能源政策解读与科普新助手2.1 能源政策解读的深度变革2.2 能源科普的创新使者 三、能源项目可行性分析新利器…...
红黑树算法笔记(二)性能对比实验
文章目录 1. 实验目标2. 对比数据结构3. 性能指标3.1 时间性能指标3.2 空间性能指标3.3 其他性能指标 4. 测试场景4.1 数据集特性变化4.2 操作模式变化4.3 环境因素变化 5. 实验设计5.1 基准测试设计5.1.1 CRUD性能基准测试5.1.2 混合负载测试5.1.3 范围查询测试 5.2 特殊场景测…...
Nlog适配达梦数据库进行日志插入
前言 原来使用的是SQLServer数据库,使用Nlog很流畅,没有什么问题。现在有个新项目需要使用麒麟操作系统和达梦数据库,业务流程开发完成之后发现Nlog配置文件中把数据库连接内容修改之后不能执行插入操作。 原Nlog.config配置 <?xml ve…...

k8s监控方案实践(三):部署与配置Grafana可视化平台
k8s监控方案实践(三):部署与配置Grafana可视化平台 文章目录 k8s监控方案实践(三):部署与配置Grafana可视化平台一、Grafana简介1. 什么是Grafana?2. Grafana与Prometheus的关系3. Grafana应用场…...

嵌入式系统架构验证工具:AADL Inspector v1.10 全新升级
软件架构建模与早期验证是嵌入式应用的关键环节。架构分析与设计语言(AADL)是专为应用软件及执行平台架构模型设计的语言,兼具文本与图形化的双重特性。AADL Inspector是一款轻量级的独立工具: 核心处理能力包括 √ 支持处理AA…...

STM32-模电
目录 一、MOS管 二、二极管 三、IGBT 四、运算放大器 五、推挽、开漏、上拉电阻 一、MOS管 1. MOS简介 这里以nmos管为例,注意箭头方向。G门极/栅极,D漏极,S源极。 当给G通高电平时,灯泡点亮,给G通低电平时&a…...

华为云Flexus+DeepSeek征文|从开通到应用:华为云DeepSeek-V3/R1商用服务深度体验
前言 本文章主要讲述在华为云ModelArts Studio上 开通DeepSeek-V3/R1商用服务的流程,以及开通过程中的经验分享和使用感受帮我更多开发者,在华为云平台快速完成 DeepSeek-V3/R1商用服务的开通以及使用入门注意:避免测试过程中出现部署失败等问…...

鸿蒙NEXT开发动画案例5
1.创建空白项目 2.Page文件夹下面新建Spin.ets文件,代码如下: /*** TODO SpinKit动画组件 - Pulse 脉冲动画* author: CSDN—鸿蒙布道师* since: 2024/05/09*/ ComponentV2 export struct SpinFive {// 参数定义Require Param spinSize: number 48;Re…...
面试篇:Spring MVC
基础概念 什么是Spring MVC? Spring MVC 是 Spring Framework 提供的一个基于 Servlet 的 Web 框架,属于 MVC(Model-View-Controller)架构的一种实现。它通过 DispatcherServlet 作为前端控制器,对请求进行分发和调度…...

ctfshow——web入门351~356
SSRF没有出网的部分 web入门351 $ch curl_init($url); 作用:初始化一个 cURL 会话,并设置目标 URL。解释: curl_init($url) 创建一个新的 cURL 资源,并将其与 $url 关联。这里的 $url 是用户提供的,因此目标地址完全…...
C++中六个特殊成员函数的关系
C中六个特殊成员函数的关系 C11之后的版本每个类有六个特殊的成员函数,之所以特殊是因为它们可以在各种情况下由编译器自动提供; 默认构造函数、复制构造函数、复制赋值运算符、析构函数、移动构造函数、移动赋值运算符 关系规则: 1、如果…...

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】金融风控分析案例-10.1 风险数据清洗与特征工程
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 PostgreSQL金融风控分析案例:风险数据清洗与特征工程实战一、案例背景:金融风控数据处理需求二、风险数据清洗实战(一)缺失值…...

美女热舞混剪视频批量剪辑生产技术实践:智能处理与原创性提升方案解析
一、引言:短视频工业化生产的技术转型 在美女类短视频内容运营中,通过标准化技术流程实现「高质量、规模化」产出成为核心需求。本文结合实战经验,解析如何通过智能素材重组、AI 语音合成、动态元素叠加等技术手段,构建自动化生产…...
破局智算瓶颈:400G光模块如何重构AI时代的网络神经脉络
一、技术演进与市场需求双重驱动 在数字化转型浪潮下,全球互联网流量正以每年30%的复合增长率持续攀升。根据Dell’Oro Group最新报告,2023年400G光模块市场规模已突破15亿美元,预计2026年将占据数据中心光模块市场60%以上份额。这种爆发式增…...
python标准库--collections - 高性能数据结构在算法比赛的应用
目录 一、deque双端队列 1.头部删除元素popleft() 2.BFS(广度优先搜索)优化 3.滑动窗口(双指针) 4.实现栈或队列 5. 双向遍历与操作 一、deque双端队列 特点:支持两端 O (1) 时间复杂度的…...

神经网络基础-从零开始搭建一个神经网络
一、什么是神经网络 人工神经网络(Articial Neural Network,简写为ANN)也称为神经网络(NN),是一种模仿生物神经网络和功能的计算模型,人脑可以看做是一个生物神经网络,由众多的神经元连接而成,各个神经元传递复杂的电信号,树突接收到输入信号,然后对信号进行处理,通…...
【Go】优化文件下载处理:从多级复制到零拷贝流式处理
在开发音频处理服务过程中,我们面临一个常见需求:从网络下载音频文件并保存到本地。这个看似简单的操作,实际上有很多优化空间。本文将分享一个逐步优化的过程,展示如何从一个基础实现逐步改进到高效的流式下载方案。 初始实现&a…...
Java 显式锁与 Condition 的使用详解
Java 显式锁与 Condition 的使用详解 在多线程编程中,线程间的协作与同步是核心问题。Java 提供了多种机制来实现线程同步,除了传统的 synchronized 关键字外,ReentrantLock 和 Condition 是更灵活且功能强大的替代方案。本文将详细介绍显式…...
android ViewModel liveData无法监听之多线程下activityViewModels不安全
我们一般的,会遇到liveData无法监听到结果,可能存在主要2种可能: liveData没有正确注册;liveData连续多次设置值,中间的值,会被丢弃,但最后一次是能监听到的。 但是我们容易忽略一种case&…...

#Redis黑马点评#(五)Redisson原理详解
目录 一 基于Redis的分布式锁优化 二 Redisson 1 实现步骤 2 Redisson可重入锁机制 3 Redisson可重试机制 4 Redisson超时释放机制 5 RedissonMultiLock解决主从一致性 三 trylock与lock两者有何区别 四 Redis优化秒杀 一 基于Redis的分布式锁优化 二 Redisson Redis…...

23.(vue3.x+vite)引入组件并动态切换(component)
让多个组件使用同一个挂载点,并动态切换,这就是动态组件 效果截图 A组件代码: <template><div><div>{{message }}</</...

VBA会被Python代替吗
VBA不会完全被Python取代、但Python在自动化、数据分析与跨平台开发等方面的优势使其越来越受欢迎、两者将长期并存且各具优势。 Python以其易于学习的语法、强大的开源生态系统和跨平台支持,逐渐成为自动化和数据分析领域的主流工具。然而,VBA依旧在Exc…...
2025 年福建省职业院校技能大赛网络建设与运维赛项Linux赛题解析
准备环境:系统安装及网络配置 [!TIP] 接下来将完全按照国赛评分标准进行,过程中需要掌握基础的Linux命令以及理解Linux系统,建议大家在做题前将Linux基础命令熟练运用 网络建设与运维赛项详细教程请联系主页一、X86架构计算机操作系统安装…...

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(三)完结
10 消息服务详情 10.1 本章定义实现加工管理概念所需的消息服务。这些消息已在第8.1节中初步介绍。 协议无关性:这些服务独立于所使用的消息协议,可映射至SECS-II(SEMI E5)或其他类似协议。 10.1.1 消息服务定义内容包括&#…...

MySQL数据库创建、删除、修改
一:建库建表 我们以学校体系进行建表。将数据库命名为school。 以下代码中的大写均可小写不影响。如CREATE DATABASE与create database相同 四个关键的实体分别是学院、老师、学生和课程,其中,学生跟学院是从属关系,这个关系从…...