【TS学习】(15)分布式条件特性
在 TypeScript 中,分布式条件类型(Distributive Conditional Types) 是一种特殊的行为,发生在条件类型作用于裸类型参数(Naked Type Parameter) 时。这种特性使得条件类型可以“分布”到联合类型的每个成员上,从而对联合类型进行逐个处理。
1. 分布式条件类型的基本概念
(1) 定义
- 当条件类型作用于一个裸类型参数(即没有被包裹的泛型参数),并且该参数是一个联合类型时,TypeScript 会将条件类型“分发”到联合类型的每个成员上。
- 这种行为称为分布式条件类型。
(2) 语法
type Distributed<T> = T extends U ? X : Y;
- 如果
T是一个联合类型(如A | B | C),则条件类型会分别对A、B和C应用T extends U ? X : Y,并将结果重新组合成一个新的联合类型。
2. 示例:分布式条件类型的作用
示例 1:基本行为
type IsString<T> = T extends string ? true : false;type Result = IsString<string | number>; // true | false
在这里:
string | number是一个联合类型。- 条件类型
IsString会被“分发”到string和number上:- 对
string:string extends string ? true : false→true - 对
number:number extends string ? true : false→false
- 对
- 最终结果是
true | false。
示例 2:提取字符串类型
type ExtractStrings<T> = T extends string ? T : never;type Result = ExtractStrings<string | number | boolean>; // string
在这里:
ExtractStrings会逐个检查联合类型的每个成员:- 对
string:string extends string ? string : never→string - 对
number:number extends string ? number : never→never - 对
boolean:boolean extends string ? boolean : never→never
- 对
- 最终结果是
string。
3. 阻止分布式条件类型
如果不想让条件类型“分布”,可以通过将裸类型参数包裹起来(例如使用数组或元组)来阻止分发。
示例:阻止分发
type IsString<T> = [T] extends [string] ? true : false;type Result = IsString<string | number>; // false
在这里:
[T]将T包裹在数组中,阻止了分发。- 整个联合类型
string | number被视为一个整体,而不是逐个成员处理。 - 因为
string | number不是string的子类型,所以结果是false。
4. 实际应用场景
分布式条件类型在实际开发中有许多用途,以下是一些常见的场景:
(1) 过滤联合类型
你可以使用分布式条件类型从联合类型中提取满足条件的成员。
示例:过滤出可调用的类型
type FilterCallable<T> = T extends (...args: any[]) => any ? T : never;type MixedTypes = string | (() => void) | number | ((x: number) => number);type CallableTypes = FilterCallable<MixedTypes>; // () => void | ((x: number) => number)
在这里:
FilterCallable提取了所有可调用的类型。
(2) 提取键名
你可以使用分布式条件类型提取对象的键名。
示例:提取值为字符串的键
type KeysOfType<T, U> = {[K in keyof T]: T[K] extends U ? K : never;
}[keyof T];type Data = {name: string;age: number;email: string;
};type StringKeys = KeysOfType<Data, string>; // "name" | "email"
在这里:
KeysOfType提取了值类型为string的键名。
(3) 类型转换
你可以使用分布式条件类型对联合类型的每个成员进行转换。
示例:为每个成员添加前缀
type AddPrefix<T, Prefix extends string> = T extends string? `${Prefix}${T}`: never;type Colors = "red" | "green" | "blue";type PrefixedColors = AddPrefix<Colors, "color_">; // "color_red" | "color_green" | "color_blue"
在这里:
AddPrefix为联合类型的每个成员添加了前缀。
5. 注意事项
(1) 裸类型参数是关键
- 分布式条件类型只会在裸类型参数上触发。
- 如果类型参数被包裹(例如放在数组或元组中),分发行为会被阻止。
示例:裸类型与包裹类型的区别
type Distribute<T> = T extends string ? true : false;
type NoDistribute<T> = [T] extends [string] ? true : false;type Result1 = Distribute<string | number>; // true | false
type Result2 = NoDistribute<string | number>; // false
(2) 避免意外分发
- 如果不希望触发分发,可以通过包裹类型参数来显式阻止。
6. 总结
- 分布式条件类型的核心作用:
- 对联合类型的每个成员逐个应用条件类型。
- 支持灵活地过滤、转换和操作联合类型。
- 关键点:
- 裸类型参数是触发分发的关键。
- 可以通过包裹类型参数阻止分发。
- 实际场景:
- 过滤联合类型。
- 提取键名或特定类型的成员。
- 动态转换联合类型的成员。
相关文章:
【TS学习】(15)分布式条件特性
在 TypeScript 中,分布式条件类型(Distributive Conditional Types) 是一种特殊的行为,发生在条件类型作用于裸类型参数(Naked Type Parameter) 时。这种特性使得条件类型可以“分布”到联合类型的每个成员…...
Android 小组件
小部件的布局文件支持如下布局: FrameLayout LinearLayout RelativeLayout GridLayout 以及如下控件 AnalogClock Button Chronometer ImageButton ImageView ProgressBar TextView ViewFlipper ListView GridView StackView AdapterViewFlipper 应该不止这些有空…...
搭建开源笔记平台:outline
折腾的意义 为什么要自己搭建一个笔记平台?没理由,就是突然想试试。有时候突然有个想法,搜了一下正好有合适的方案,就顺手试一下。 其实已经有很多成熟的笔记软件,例如Notion/OneNote,但谁不想要一个数据完…...
Unity编辑器功能及拓展(2) —Gizmos编辑器绘制功能
Unity中的Gizmos功能是用于在场景视图中绘制辅助图形或图标的工具,帮助开发者在编辑模式下直观调试和可视化游戏对象的位置、范围、方向等信息。 一.定义概述 Gizomsd 概述 Gizoms是Unity提供的一个API,或者叫做一个工具类,包含一系列静态…...
电脑屏幕亮度随心控,在Windows上自由调整屏幕亮度的方法
调整电脑屏幕的亮度对于保护视力和适应不同环境光线条件非常重要。无论是在白天强光下还是夜晚昏暗环境中,合适的屏幕亮度都能让您的眼睛更加舒适。本文中简鹿办公小编将向您介绍几种在 Windows 系统中调整屏幕亮度的方法。 方法一:使用快捷键 大多数笔…...
presto行转列
presto的行列转换和spark、hive一样也是通过外链语句实现的,只不过语法和关键子有点不同,如下 with tmp1 as (select 1,2,3 as a1,4,5,6 as a2 ) select * from tmp1 cross join unnest(split(tmp1.a1, ,),split(tmp1.a2, ,) ) as b(a1s,a2s) 结果如下...
MySQL 5.7 Online DDL 技术深度解析
14.13.1 在线DDL操作 索引操作主键操作列操作生成列操作外键操作表操作表空间操作分区操作 索引操作 下表概述了对索引操作的在线DDL支持情况。星号表示有附加信息、例外情况或依赖条件。有关详细信息,请参阅语法和使用说明。 操作原地执行重建表允许并发DML仅修…...
【汽车功能安全:软件与硬件缺一不可】
随着汽车变得越来越智能,功能安全就成为汽车电子系统不可回避的标准体系,日益复杂的功能导致了汽车中电子元件的数量和复杂性的指数级增长(Leen)。如今高级别汽车拥有多达90个电子控制单元(ECU),…...
docker打包使用有头模式playwright
1.打包镜像 创建Dockerfile文件如下 # playywright 官方镜像 FROM mcr.microsoft.com/playwright:v1.37.0-jammy# 设置非交互式环境变量和时区 ENV DEBIAN_FRONTENDnoninteractive ENV TZEtc/UTC# 安装 Python 3.9 和 pip(修复时区阻塞问题) RUN apt-g…...
TCP/IP协议的应用层与传输层
TCP/IP协议簇是互联网的核心通信框架,定义了数据如何在网络中封装、寻址、传输和路由(确定数据包从源主机到目标主机的传输路径的过程)。 应用层 直接面向用户和应用,负责实现网络服务的具体功能(如网页浏览、文件传输…...
51c自动驾驶~合集15
我自己的原文哦~ https://blog.51cto.com/whaosoft/11720657 #DRAMA 首个基于Mamba的端到端运动规划器(新加坡国立) 运动规划是一项具有挑战性的任务,在高度动态和复杂的环境中生成安全可行的轨迹,形成自动驾驶汽车的核心能…...
拼多多 anti-token unidbg 分析
声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 逆向分析 版本7.3-7.4 都试过加密没什…...
【Git】5 个分区的切换方式及示例
目录 1. **工作区(Working Directory)**2. **缓存区(Stage/Index)**3. **本地仓库(Local Repository)**4. **远程仓库(Remote Repository)**5. **贮藏区(Stash࿰…...
Java高频面试之并发编程-02
hello啊,各位观众姥爷们!!!本baby今天来报道了!哈哈哈哈哈嗝🐶 面试官:进程和线程的区别是什么? 1. 资源分配与独立性 进程: 独立性:每个进程拥有独立的内存…...
openwebui和keycloak集成,使用keycloak的用户名和密码登录
1,实现效果 使用keycloak定义的用户名和密码,直接登录openwebui 2,实现原理 keycloak中用户信息中包含用户名和密码,以及email。 使用keycloak中的用户名和密码登录之后,会用email创建一个openwebui的账号。之后每次…...
html实现手势密码
<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>手势密码</title><style>body {font-fam…...
【区块链安全 | 第八篇】多签机制及恶意多签
部分参考:慢雾科技 文章目录 为什么需要多签多签机制Tron钱包下的恶意多签Tron 钱包多签权限分类Tron 多签机制的运作方式 恶意多签的过程黑客通过多签机制控制账户黑客剥夺用户权限,完全控制账户 恶意多签成因 在区块链中,多签(M…...
项目如何安装本地tgz包并配置局部registry
一、判断包来源是否正确 1. 检查url curl <registry_url>2. 查看包是否存在 npm view <package_name> --registry<registry_url>二、局部registry配置步骤: 1. 全局配置 如果你希望对所有项目生效,可以将这行配置添加到全局.npmr…...
二月公开赛Web-ssrfme
目录 环境搭建 题目分析 分析代码 解题过程 Redis未授权访问 寻找Flag 环境搭建 进入含有docker-compose.yml的文件内,拉取容器镜像 docker-compose up -d 题目分析 访问容器地址172.25.254.200:8091查看题目 分析代码 url通过GET请求访问界面,…...
JavaRedis和数据库相关面试题
JavaRedis面试题 1. Redis是什么以及Redis为什么快? Redis(Remote Dictionary Server)是一个开源的内存键值数据库,支持多种数据结构(如字符串、哈希、列表、集合等),并提供持久化、复制、…...
告别枯燥工作,走向自动化
嘿,小伙伴们!今天给你们介绍两款超实用的RPA办公自动化软件,用它们,再也不用像机器一样做重复劳动啦,超省时间! 工具名称:影刀RPA(类似产品,八爪鱼 RPA,操作上…...
Spring的 @Conditional @ConditionalOnProperty 注解 笔记250330
Spring的 Conditional ConditionalOnProperty 注解 Spring 的 Conditional 与 ConditionalOnProperty 注解详解 在 Spring 框架中,Conditional 和 ConditionalOnProperty 是用于动态控制 Bean 注册的重要注解。虽然它们都服务于条件化配置,但定位和使用…...
可信数据空间:构筑安全可控数据流通
前言:可信数据空间是一种数据基础设施,发展可信数据空间是全国及各地数据基础设施建设的重要方面。国内数据空间的探索和实践仍然数据探索阶段。本期分享:可信数据空间构筑安全可控数据流通,包括可信数据空间技术介绍、如何助力数…...
Zookeeper特性与节点数据类型
数据结构和监听机制 CP 文件系统形式存储 观察者模式监听节点数据变化、 临时节点客户端超时或发生异常节点就会删除 2888同步数据 3888选举端口 1.什么是Zookeeper ZooKeeper 是一个开源的分布式协调框架,是Apache Hadoop 的一个子项目,主要用来…...
【C++游戏引擎开发】《线性代数》(6):SVD(奇异值分解)的数学原理与实现
一、奇异值分解(SVD)的数学定义 奇异值分解(Singular Value Decomposition,SVD)是一种将任意实数或复数矩阵分解为三个特定矩阵乘积的方法。其数学定义如下: 1.1 分解形式 给定一个秩为 r r r的矩阵 A ∈ R m n \mathbf{A} \in \mathbb{R}^{m \times n} A∈Rmn(或…...
C语言pthread库创建线程的案例
一、代码案例 #include<stdio.h> #include<stdlib.h> // 多线程库 #include<pthread.h> // 线程1的逻辑描述 void* thread_method_01(void* v){ printf("线程1执行完毕。\n"); return NULL; } // 线程2的执行逻辑 void* thread_meth…...
处理 Linux 信号:进程控制与异常管理的核心
个人主页:chian-ocean 文章专栏-Linux 前言: 在 Linux 操作系统中,信号是用于进程间通信的一种机制,能够向进程发送通知,指示某些事件的发生。信号通常由操作系统内核、硬件中断或其他进程发送。接收和处理信号是 Li…...
【蓝桥杯每日一题】4.1
🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x "今日秃头刷题,明日荣耀加冕!" 今天我们来练习二分算法 不熟悉二分算法的朋友可以看:【C语言刷怪篇】二分法_编程解决算术问题-CSDN博客 …...
分享系列项目的基础项目
本人分享了一系列的框架项目,它们共同需要依赖这个公共基础,结构如下图所示: 其中: audit: JPA的审计信息基础类auth:认证授权相关类config: 包括redis配置,client中token配置,openai文档配置…...
为 MinIO AIStor 引入模型上下文协议(MCP)服务器
Anthropic 最近宣布的模型上下文协议 (MCP) 将改变我们与技术交互的方式。它允许自然语言通信替换许多任务的复杂命令行语法。不仅如此,语言模型还可以总结传统工具的丰富输出,并以人类可读的形式呈现关键信息。MinIO 是世界领先的…...
