在一个最近的项目中,我遇到一个问题,需要验证一个对象,其键由一个常量映射动态定义,并强制至少一个键具有有效值。
挑战
我们有一个MetadataMap对象,它定义了有效的键及其对应的类型:
const MetadataMap = { userId: Number, utmSource: String, utmMedium: String, utmCampaign: String, } as const;
根据此映射,我们需要:
- 动态生成一个TypeScript接口来强制类型安全。
- 创建一个Yup验证模式,根据映射验证对象。
- 确保对象中至少一个键具有有效值(非undefined)。
- 避免硬编码键以提高解决方案的可维护性。
但是,TypeScript在编译时强制执行静态类型,而Yup处理运行时验证。
步骤1:生成接口
为了从MetadataMap生成TypeScript接口,我们使用了keyof
和映射类型。以下是我们定义它的方式:
type Metadata = { [K in keyof typeof MetadataMap]: typeof MetadataMap[K] extends NumberConstructor ? number : string; };
这种方法确保了MetadataMap的任何更新都会自动反映在Metadata接口中。例如:
// 生成的Metadata接口:
interface Metadata { userId?: number; utmSource?: string; utmMedium?: string; utmCampaign?: string; }
步骤2:动态生成Yup模式
我们需要动态创建一个与MetadataMap中的键和类型匹配的Yup模式。使用Object.keys
和reduce
,我们将每个键映射到其对应的Yup验证器:
const metadataSchema = Yup.object( Object.keys(MetadataMap).reduce((schema, key) => { const type = MetadataMap[key as keyof typeof MetadataMap]; if (type === Number) { schema[key] = Yup.number().optional(); } else if (type === String) { schema[key] = Yup.string().optional(); } return schema; }, {} as Record<string, any>) );
此方法消除了硬编码,并确保了MetadataMap中的更改会在无需手动更新的情况下反映在模式中。
步骤3:添加“至少一个键”规则
下一个挑战是确保对象中至少一个键具有定义的值。我们在Yup模式中添加了一个.test
方法:
metadataSchema.test( "at-least-one-key", "Metadata must have at least one valid key.", (value) => { if (!value || typeof value !== "object") return false; const validKeys = Object.keys(MetadataMap) as (keyof typeof MetadataMap)[]; return validKeys.some((key) => key in value && value[key] !== undefined); } );
此逻辑:
- 确保对象有效。
- 从MetadataMap动态提取有效键。
- 验证至少一个键具有非undefined值。
结果 以下是最终模式的行为:
const exampleMetadata = { userId: undefined, utmSource: "google", extraField: "invalid", // 此键被忽略。 }; metadataSchema .validate(exampleMetadata) .then(() => console.log("Validation succeeded")) .catch((err) => console.error("Validation failed:", err.errors));
在此示例中,验证成功,因为utmSource是一个具有非undefined值的有效键,即使userId未定义且extraField不是MetadataMap的一部分。
以上是使用 Yup 在 TypeScript 中动态生成接口和验证模式的详细内容。更多信息请关注PHP中文网其他相关文章!

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

Python和JavaScript在开发环境上的选择都很重要。1)Python的开发环境包括PyCharm、JupyterNotebook和Anaconda,适合数据科学和快速原型开发。2)JavaScript的开发环境包括Node.js、VSCode和Webpack,适用于前端和后端开发。根据项目需求选择合适的工具可以提高开发效率和项目成功率。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

Dreamweaver Mac版
视觉化网页开发工具

WebStorm Mac版
好用的JavaScript开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

适用于 Eclipse 的 SAP NetWeaver 服务器适配器
将Eclipse与SAP NetWeaver应用服务器集成。