讲师中心 微信公众号
AI工具推荐 视频效率加速

JSDoc中定义包含固定属性和任意扩展属性的对象类型

大静君_2574

大静君_2574

发布时间:2025-11-14 14:41:00

|

967人浏览过

|

来源于php中文网

原创

JSDoc中定义包含固定属性和任意扩展属性的对象类型

本文探讨了在jsdoc中定义具有固定强制属性和任意附加属性的对象类型的方法。通过介绍从使用`*`通配符属性到结合交叉类型以及嵌入`object.`语法的多种技术,提供了实用的代码示例,旨在帮助开发者在javascript项目中实现类型定义的灵活性与严谨性。

在JavaScript项目中,使用JSDoc进行类型注解能够显著提升代码的可读性和可维护性,尤其是在大型或团队协作项目中。然而,当我们需要定义一个对象类型,它既包含一组固定的、强制性的属性,又允许用户或系统添加任意数量的额外属性时,JSDoc的类型定义就显得尤为重要。本文将详细介绍几种实现这种灵活类型定义的方法。

1. 使用通配符属性 (*)

最直接的方法是在JSDoc的@property标签中使用通配符*来指示对象可以拥有未明确声明的属性。这种方法简单易行,但对额外属性的类型约束较弱。

示例代码:

/**
 * @typedef {Object} User
 * @property {string} name - 用户名 (必填)
 * @property {number} age - 用户年龄 (必填)
 * @property {*} [key: value] - 用户可添加的额外属性 (可选)
 */

/**
 * @type {User}
 */
const tom = {
  name: 'cx',
  age: 25,
  from: 'sh', // JSDoc/TypeScript 通常不会报错
  to: 'bj',   // JSDoc/TypeScript 通常不会报错
};

说明:

Add Typescript Best Practices
Add Typescript Best Practices

在 CLAUDE.md 中配置 TypeScript 最佳实践和代码风格规则

下载

通过在@property标签后添加*,JSDoc会理解此对象允许存在未显式声明的属性。[key: value]是一个常见的约定,表示任意键和任意值。然而,这种方法的缺点是对于这些额外属性的键名和值类型缺乏具体的约束,所有额外属性都将被视为any类型,从而降低了类型检查的严格性。这在需要更精细控制额外属性类型时可能不够理想。

2. 结合交叉类型 (&)

交叉类型允许我们将多个类型合并为一个新类型,新类型将拥有所有合并类型的成员。通过将固定属性类型与一个表示任意键值对的类型进行交叉,可以实现更清晰、更模块化的定义。

示例代码:

/**
 * @typedef {object} UserBase
 * @property {string} name - 用户名
 * @property {number} age - 用户年龄
 */

/**
 * @typedef {Object.<string, any>} DynamicProperties - 描述任意字符串键和任意值类型的对象
 */

/**
 * @typedef {UserBase & DynamicProperties} UserWithDetails - 包含固定属性和动态属性的用户详情
 */

/**
 * @type {UserWithDetails}
 */
const tom = {
  name: "cx",
  age: 25,
  from: "sh",
  to: "bj",
  occupation: "Engineer" // 允许添加更多任意属性
};

说明:

这种方法将固定属性的定义(UserBase)和动态属性的定义(DynamicProperties)分离,提高了可读性和模块性。Object.<string, any> 类型明确表示这是一个键为字符串、值为任意类型的对象。通过交叉类型 & 将 UserBase 和 DynamicProperties 结合,新类型 UserWithDetails 既保证了 name 和 age 的存在及其类型,又允许其他任意属性。这种方式在某些JSDoc解析器和TypeScript的JSDoc支持中可能提供更好的类型推断。

3. 内联 Object.<keyType, valueType>

这是一种在@typedef中直接定义一个属性,该属性本身就是一个Object.<keyType, valueType>类型,用于捕获所有未显式声明的额外属性。这种方法通常被认为是简洁且有效的。

示例代码:

/**
 * @typedef {object} User
 * @property {string} name - 用户名
 * @property {number} age - 用户年龄
 * @property {Object.<string, any>} [additionalProperties] - 额外的键值对,键为字符串,值为任意类型
 */

/**
 * @type {User}
 */
const tom = {
  name: "cx",
  age: 25,
  from: "sh", // 不再报错
  to: "bj",   // 不再报错
  email: "tom@example.com" // 允许添加更多任意属性
};

说明:

这种方法将 Object.<string, any> 直接作为 User 类型的一个属性来定义。这里的[additionalProperties]是一个可选的占位符,它实际上是声明了除了name和age之外,对象还可以包含任意数量的额外属性。在JSDoc解析器和TypeScript的JSDoc支持中,这会被解释为允许对象包含除了显式声明属性之外的任意属性。

这种方式兼顾了简洁性和表达力,是推荐的一种实践。如果需要对额外属性的类型有更严格的限制,例如所有额外属性的值都必须是字符串,可以将 any 替换为更具体的类型,例如 Object.<string, string>。

最佳实践与注意事项

  • 选择合适的粒度: 如果额外属性的类型高度不确定,可以使用 any;如果已知它们通常是某种特定类型(如 string),则使用 Object.<string, string> 可以提供更强的类型检查,从而提高代码的健壮性。
  • 工具链兼容性: 不同的JSDoc解析器或TypeScript对JSDoc的支持可能略有差异。建议在实际项目中测试所选方案,以确保其在您的开发环境中按预期工作。
  • 可读性与维护性: 尽管多种方法都能实现目标,但选择一种清晰、易于理解且符合团队规范的方式至关重要。内联 Object.<keyType, valueType> 通常被认为是简洁且足够表达意图的方案。
  • 避免过度复杂化: 如果对象结构变得过于复杂,可能需要考虑将数据拆分为多个更小的、定义清晰的类型,或者重新评估数据模型,以保持代码的整洁和易于管理。

总结

在JSDoc中定义既包含固定属性又允许任意扩展属性的对象类型是提升JavaScript项目类型描述能力的关键。通过本文介绍的通配符属性、交叉类型以及内联 Object.<keyType, valueType> 等方法,开发者可以根据具体需求选择最合适的策略。其中,内联 Object.<string, any> 或 Object.<string, string> 方式因其简洁性和有效性,在多数场景下是一个推荐的实践,它能有效平衡类型检查的严谨性与数据结构的灵活性,从而帮助构建更健壮、更易于维护的JavaScript应用程序。

热门AI工具

更多
PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

272

2026.02.13

TypeScript全栈项目架构与接口规范设计
TypeScript全栈项目架构与接口规范设计

本专题面向全栈开发者,系统讲解基于 TypeScript 构建前后端统一技术栈的工程化实践。内容涵盖项目分层设计、接口协议规范、类型共享机制、错误码体系设计、接口自动化生成与文档维护方案。通过完整项目示例,帮助开发者构建结构清晰、类型安全、易维护的现代全栈应用架构。

500

2026.02.25

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

351

2026.03.13

TypeScript 全栈开发进阶指南
TypeScript 全栈开发进阶指南

面向有 JavaScript 基础的开发者,深入讲解 TypeScript 的类型系统与全栈开发实践。

266

2026.06.03

TypeScript Node.js 全栈工程化与Monorepo架构实践
TypeScript Node.js 全栈工程化与Monorepo架构实践

本专题围绕 TypeScript 在 Node.js 全栈开发中的工程化实践展开,系统讲解 Monorepo 架构设计、包管理策略、模块复用机制以及服务端与前端统一类型系统的构建方法。通过真实项目案例,帮助开发者提升大型全栈项目的可维护性与协作效率。

538

2026.06.16

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5759

2023.08.02

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1638

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2444

2023.09.04

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

100

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.1万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn