TS常见内置映射类型的实现及应用场景

以下是 TypeScript 在前端项目中 常用的映射类型(Mapped Types),结合具体场景和代码示例,帮助开发者高效处理复杂类型:


一、基础映射类型

1. Partial<T>

作用:将对象类型 T 的所有属性变为可选。
实现

type Partial<T> = {[P in keyof T]?: T[P];
};

应用场景

  • 表单的初始状态(部分字段可选)。

  • API 请求的更新参数(只需传部分字段)。

interface User {name: string;age: number;
}type PartialUser = Partial<User>;
// { name?: string; age?: number }const initialForm: PartialUser = {}; // 合法

2. Required<T>

作用:将对象类型 T 的所有属性变为必填。
实现

type Required<T> = {[P in keyof T]-?: T[P]; // "-?" 表示移除可选修饰符
};

应用场景

  • 严格校验配置对象(确保所有字段必须存在)。

type StrictConfig = Required<{ apiUrl?: string }>;
// { apiUrl: string }const config: StrictConfig = { apiUrl: "https://api.com" }; // 必须填写

3. Readonly<T>

作用:将对象类型 T 的所有属性变为只读。
实现

type Readonly<T> = {readonly [P in keyof T]: T[P];
};

应用场景

  • 全局常量配置(防止意外修改)。

  • React 组件的默认 Props。

const defaultProps: Readonly<{ color: string }> = { color: "red" };
defaultProps.color = "blue"; // 编译报错:只读属性

4. Pick<T, K>

作用:从对象类型 T 中选取指定键 K 的子集。
实现

type Pick<T, K extends keyof T> = {[P in K]: T[P];
};

应用场景

  • 组件 Props 的透传(如仅暴露部分属性)。

  • 过滤敏感字段(如排除 password)。

interface User {id: string;name: string;password: string;
}type SafeUser = Pick<User, "id" | "name">;
// { id: string; name: string }

5. Omit<T, K>

作用:从对象类型 T 中排除指定键 K 的属性。
实现

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

应用场景

  • 覆盖组件默认 Props。

  • 忽略不需要的 API 响应字段。

type UserWithoutPassword = Omit<User, "password">;
// { id: string; name: string }

6. Record<K, T>

作用:创建一个键类型为 K,值类型为 T 的对象类型。
实现

type Record<K extends keyof any, T> = {[P in K]: T;
};

应用场景

  • 枚举映射(如国际化词表)。

  • Redux 的 Action 类型集合。

type Language = "en" | "zh";
type I18N = Record<Language, { title: string }>;const i18n: I18N = {en: { title: "Hello" },zh: { title: "你好" },
};

二、进阶映射类型

1. 条件映射:{ [K in keyof T]: T[K] extends U ? X : Y }

作用:根据条件筛选或转换属性类型。
应用场景

  • 提取所有函数属性。

  • 将数字属性转为字符串。

type FunctionKeys<T> = {[K in keyof T]: T[K] extends Function ? K : never;
}[keyof T]; // 最终得到联合类型type UserMethods = FunctionKeys<User>; // "update" | "delete"

2. 深度映射:DeepReadonly / DeepPartial

作用:递归处理嵌套对象属性。
实现

type DeepReadonly<T> = {readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K];
};type DeepPartial<T> = {[K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

应用场景

  • 深度冻结状态(如 Redux 的不可变状态树)。

  • 表单的嵌套字段可选。

interface NestedData {user: { name: string; address: { city: string } };
}type ReadonlyData = DeepReadonly<NestedData>;
// user 和 address 均为只读

3. 联合类型映射:{ [K in keyof T]: T[K] }

作用:将联合类型转为交叉类型或其他结构。
应用场景

  • 合并多个接口类型。

type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;type Combined = UnionToIntersection<{ a: 1 } | { b: 2 }>;
// { a: 1 } & { b: 2 }

三、前端实战场景

场景 1:动态表单控件 Props

根据表单字段类型生成对应的 UI 控件 Props。

type FieldType = "text" | "number" | "date";type FieldProps<T extends FieldType> = {type: T;value: T extends "text" ? string :T extends "number" ? number :Date;
};function renderField<T extends FieldType>(props: FieldProps<T>) {// 根据 type 渲染不同控件
}

场景 2:Redux Action 类型安全

自动推导 Action 类型,避免手动定义。

type ActionMap<M extends { [key: string]: any }> = {[Key in keyof M]: M[Key] extends undefined? { type: Key }: { type: Key; payload: M[Key] };
};type Actions = ActionMap<{LOGIN: { username: string };LOGOUT: undefined;
}>;// 结果:
// { LOGIN: { type: "LOGIN"; payload: { username: string } }, 
//   LOGOUT: { type: "LOGOUT" } }

场景 3:组件 Props 动态扩展

通过映射类型动态生成复合 Props。

type WithClassName<T> = T & { className?: string };type ButtonProps = WithClassName<{onClick: () => void;text: string;
}>;// 结果:{ onClick: () => void; text: string; className?: string }

四、总结

映射类型核心能力典型场景
Partial<T>属性可选化表单初始值、更新参数
Pick<T, K> / Omit<T, K>属性筛选或排除组件 Props 透传
Record<K, T>键值对批量定义枚举映射、Action 集合
条件映射按条件转换属性类型动态表单控件
深度映射递归处理嵌套对象不可变状态、复杂表单

掌握这些映射类型后,可以大幅减少重复代码,提升前端项目的类型安全性和可维护性

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

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

相关文章

介绍如何使用YOLOv8模型进行基于深度学习的吸烟行为检测

下面为你详细介绍如何使用YOLOv8模型进行基于深度学习的吸烟行为检测&#xff0c;包含环境配置、数据准备、模型训练以及推理等步骤。 1. 环境配置 首先&#xff0c;你需要安装必要的库&#xff0c;主要是ultralytics库&#xff0c;它包含了YOLOv8模型。你可以使用以下命令进…

AI-医学影像分割方法与流程

AI医学影像分割方法与流程–基于低场磁共振影像的病灶识别 – 作者:coder_fang AI框架&#xff1a;PaddleSeg 数据准备&#xff0c;使用MedicalLabelMe进行dcm文件标注&#xff0c;产生同名.json文件。 编写程序生成训练集图片&#xff0c;包括掩码图。 代码如下: def doC…

【Python】09、字典

文章目录 1. 字典简介2. 字典的使用2.1 字典创建2.2 字典值获取2.3 字典值修改2.4 字典的删除 3. 字典的遍历 1. 字典简介 字典(dict)属于一种新的数据结构&#xff0c;称为映射(mapping)。 字典的作用和列表类似&#xff0c;但是查询性能比列表好&#xff1b;在字典中每个元…

【贪心算法4】

力扣452.用最少数量的剪引爆气球 链接: link 思路 这道题的第一想法就是如果气球重叠得越多那么用箭越少&#xff0c;所以先将气球按照开始坐标从小到大排序&#xff0c;遇到有重叠的气球&#xff0c;在重叠区域右边界最小值之前的区域一定需要一支箭&#xff0c;这道题有两…

SGMEA: Structure-Guided Multimodal Entity Alignment

3 Method 3.1 Problem Definition 3.2 Framework Description 总体框架如图2所示&#xff0c;由三个主要部分组成&#xff1a;初始嵌入采集模块、结构引导模块和模态融合模块。 3.3 Initial Embedding Acquisition 3.3.1 Structural Embedding 3.3.2 Relation, Attribute, …

KY-038 声音传感器如何工作以及如何将其与 ESP32 连接

想为您的项目赋予声音感!然后跟着做,因为在这个项目中,我们将连接一个声音传感器,用它构建一些有趣的项目。我们使用的 KY-038 声音传感器使用电容式麦克风来检测声波,这为我们提供了稳定性和可靠性的完美平衡。因此,在本文中,我们决定将 KY-038 传感器与 ESP32 连接,并…

《基于超高频RFID的图书馆管理系统的设计与实现》开题报告

一、研究背景与意义 1.研究背景 随着信息化时代的到来&#xff0c;运用计算机科学技术实现图书馆的管理工作已成为优势。更加科学地管理图书馆会大大提高工作效率。我国的图书管理体系发展经历了三个阶段&#xff1a;传统图书管理模式、现代图书管理模式以及基于无线射频识别&…

[local-file-system]基于服务器磁盘的本地文件存储方案

[local-file-system]基于服务器磁盘的本地文件存储方案 仅提供后端方案 github 环境 JDK11linux/windows/mac 应用场景 适用于ToB业务&#xff0c;中小企业的单体服务&#xff0c;仅使用磁盘存储文件的解决方案 仅使用服务器磁盘存储 与业务实体相结合的文件存储方案&…

P5708 【深基2.习2】三角形面积(洛谷—python)

题目描述 一个三角形的三边长分别是 a、b、c&#xff0c;那么它的面积为 p(p−a)(p−b)(p−c)​&#xff0c;其中 p21​(abc)。输入这三个数字&#xff0c;计算三角形的面积&#xff0c;四舍五入精确到 1 位小数。 输入格式 第一行输入三个实数 a,b,c&#xff0c;以空格隔开…

智慧加油站小程序数据库设计文档

智慧加油站系统 - 数据库与API设计文档 1. 数据库设计 1.1 ER模型 系统的核心实体关系如下&#xff1a; 用户(User) ---< 订单(Order) ---< 加油记录(RefuelRecord)| | || | vv v …

C++博客分享

本周的一些 C视频分享, 或许后续会做一些内容总结. 博客 Polymorphic, Defaulted EqualityConstexpr factors_ofC26: Removing language featuresBypassing the branch predictor Meeting C 2024 Clean CMake for C (library) developers - Kerstin KellerAn Introduction …

【蓝桥杯每日一题】3.16

&#x1f3dd;️专栏&#xff1a; 【蓝桥杯备篇】 &#x1f305;主页&#xff1a; f狐o狸x 目录 3.9 高精度算法 一、高精度加法 题目链接&#xff1a; 题目描述&#xff1a; 解题思路&#xff1a; 解题代码&#xff1a; 二、高精度减法 题目链接&#xff1a; 题目描述&…

vue 仿deepseek前端开发一个对话界面

后端&#xff1a;调用deepseek的api&#xff0c;所以返回数据格式和deepseek相同 {"model": "DeepSeek-R1-Distill-Qwen-1.5B", "choices": [{"index": 0, "delta": {"role": "assistant", "cont…

SpringMVC(五)拦截器

目录 拦截器基本概念 一 单个拦截器的执行 1 创建拦截器 2 SpringMVC配置&#xff0c;并指定拦截路径。 3 运行结果展示&#xff1a; 二 多个拦截器的执行顺序 三 拦截器与过滤器的区别 拦截器基本概念 SpringMVC内置拦截器机制&#xff0c;允许在请求被目标方法处理的…

Hive SQL 精进系列:PERCENTILE_APPROX 搞定分位数

目录 一、引言二、percentile_approx 函数基础2.1 基本语法参数解释返回值简单示例 三、应用场景3.1 数据分析与报告3.2 数据清洗与异常值检测3.3 性能监控与优化 四、使用注意事项4.1 数据类型要求4.2 精度与性能平衡4.3 空值处理 五、总结 一、引言 百分位数作为一种常用的统…

pytorch快速入门——手写数字分类GPU加速

&#x1f451;主页&#xff1a;吾名招财 &#x1f453;简介&#xff1a;工科学硕&#xff0c;研究方向机器视觉&#xff0c;爱好较广泛… ​&#x1f4ab;签名&#xff1a;面朝大海&#xff0c;春暖花开&#xff01; pytorch快速入门——手写数字分类GPU加速 一、tensor1&#…

【开源免费】基于SpringBoot+Vue.JS电商应用系统(JAVA毕业设计)

本文项目编号 T 242 &#xff0c;文末自助获取源码 \color{red}{T242&#xff0c;文末自助获取源码} T242&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

经历过的IDEA+Maven+JDK一些困惑

注意事项&#xff1a;由于使用过程中是IDEA绑定好另外2个工具&#xff0c;所以报错统一都显示在控制台&#xff0c;但要思考和分辨到底是IDEA本身问题导致的报错&#xff0c;还是maven导致的 使用前的配置 编辑期 定义&#xff1a;指的是从open projects开始&#xff0c;到执行…

【推理】大模型ReasonGraph:推理路径的可视化论文及代码分析

ReasonGraph:推理路径的可视化 ReasonGraph demo http://192.168.50.197:5001/ 作者的其他论文 ** ** LLM推理方法的相关工作

学习路之TP6 --重写vendor目录下的文件(服务覆盖command---优点:命令前后一致)

学习路之TP6 --重写vendor目录下的文件 一、新建命令文件&#xff1a;二、复制修改&#xff1a;Server.php三、新建服务类&#xff1a;WorkmanService.php四、注册服务五、运行效果 有需求要重写vendor\topthink\think-worker\src\command\Server.php 以实现修改代码 一、新建命…