0

0

JSDoc 中定义包含固定属性和可变额外属性的对象类型

霞舞

霞舞

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

|

707人浏览过

|

来源于php中文网

原创

JSDoc 中定义包含固定属性和可变额外属性的对象类型

本教程探讨在 jsdoc 中定义具有固定必选属性和任意可选额外属性的对象类型。我们将介绍两种主要策略:使用通配符属性实现高度灵活性,以及结合交叉类型与字典类型实现更强的类型约束,以确保类型定义的准确性和避免因额外属性导致的类型检查错误。

在 JavaScript 项目中,JSDoc 是一种强大的工具,用于为代码添加类型注解,从而提升开发效率和代码可维护性。然而,在某些场景下,我们需要定义一种对象类型,它既包含一组固定的、明确定义的属性,又允许开发者自由添加任意数量的额外属性。例如,一个 User 对象可能需要强制包含 name 和 age 属性,同时又允许添加 from、to 等动态属性。本文将详细介绍如何在 JSDoc 中实现这种灵活的对象类型定义。

1. 场景需求分析

假设我们有一个 User 类型,要求:

  • 必须包含 name (字符串) 和 age (数字) 属性。
  • 可以包含任意数量的其他属性,这些属性的键和值类型可以是任意的,或者有特定的约束。

以下是一个初始的 JSDoc 定义,它会在添加额外属性时引发类型错误:

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

/**
 * @type {User}
 */
const tom = {
  name: 'cx',
  age: 25,
  from: 'sh', // 预期会报错
  to: 'bj',   // 预期会报错
};

为了解决这个问题,我们可以采用以下两种 JSDoc 定义策略。

2. 方法一:使用通配符属性 (*) 允许任意额外属性

最直接且最灵活的方法是使用 JSDoc 的通配符属性 (*) 来指示对象可以拥有除明确定义属性之外的任何其他属性。这种方法不对额外属性的键或值进行类型限制。

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

/**
 * @type {User}
 */
const tom = {
  name: 'cx',
  age: 25,
  from: 'sh', // 不再报错
  to: 'bj',   // 不再报错
  isActive: true, // 同样不会报错
};

说明:

  • @property {*} [key: value] 告诉 JSDoc,除了 name 和 age 之外,该对象可以包含任何键 (key) 和任何值 (value) 的属性。
  • [key: value] 是一个占位符,表示任意键值对
  • * 表示这些额外属性的值可以是任何类型。

优点:

  • 高度灵活: 允许添加任何类型的额外属性,无需提前声明。
  • 简单易懂: 定义直观,易于理解。

缺点:

一点PPT
一点PPT

一句话生成专业PPT,AI自动排版配图

下载
  • 类型安全性低: 对额外属性的类型没有任何约束,可能导致潜在的运行时错误,因为类型检查器不会对这些属性的值进行验证。

3. 方法二:结合交叉类型 (&) 与字典类型 (Object.<string, Type>) 实现类型约束

当我们需要对额外属性的类型进行更具体的约束时(例如,所有额外属性的值都必须是字符串),可以使用 JSDoc 的交叉类型 (&) 结合字典类型 Object.<string, Type>。这种方法允许我们定义一个具有特定类型签名的额外属性集合,并将其与固定属性合并。

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

/**
 * @typedef {Object.<string, string>} AdditionalProperties - 额外属性,键为字符串,值为字符串
 */

/**
 * @typedef {UserBase & AdditionalProperties} User - 包含固定属性和额外字符串属性的用户类型
 */

/**
 * @type {User}
 */
const tom = {
  name: "cx",
  age: 25,
  from: "sh", // 不再报错
  to: "bj",   // 不再报错
  // isActive: true, // 如果这里尝试添加非字符串值,将引发类型错误
};

/**
 * 尝试添加一个不符合类型约束的属性
 * @type {User}
 */
const invalidTom = {
  name: "john",
  age: 30,
  country: "USA",
  // isVerified: true, // 错误:'true' 不是 string 类型
};

说明:

  • 我们首先定义了 UserBase,它包含所有固定的必选属性。
  • @typedef {Object.<string, string>} AdditionalProperties 定义了一个字典类型,其中所有的键都是 string,所有的值也都是 string。你可以根据需要将 string 替换为其他类型(例如 number、boolean 或 any)。
  • @typedef {UserBase & AdditionalProperties} User 使用交叉类型 (&) 将 UserBase 和 AdditionalProperties 合并。这意味着 User 类型必须满足 UserBase 的所有要求,同时其所有未明确定义的属性都必须符合 AdditionalProperties 的类型签名。

优点:

  • 类型安全性高: 对额外属性的键和值类型有明确的约束,有助于在开发阶段捕获类型错误。
  • 结构清晰: 将固定属性和额外属性的类型定义分离,提高了可读性。

缺点:

  • 略复杂: 需要定义多个 typedef 来组合类型。
  • 约束性强: 如果额外属性的类型非常多样,可能需要更复杂的 Object.<string, Type> 定义,甚至可能需要回退到 Object.<string, *>。

总结与建议

在 JSDoc 中定义同时包含固定属性和可变额外属性的对象类型时,选择哪种方法取决于你对类型安全性和灵活性的具体需求:

  1. 当额外属性的类型完全不可预测,且你更看重灵活性和简洁性时,请使用 @property {*} [key: value]。这种方法最简单,但牺牲了额外属性的类型检查。
  2. 当需要对额外属性的类型进行约束,以提高代码的健壮性和可维护性时,请使用交叉类型结合 Object.<string, Type>。这种方法提供了更强的类型保证,尤其适用于所有额外属性都遵循相似类型模式的场景。

通过合理运用这些 JSDoc 策略,你可以为复杂的 JavaScript 对象提供清晰、准确的类型定义,从而提升项目的整体质量和开发体验。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

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

1031

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

367

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.30

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

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

760

2023.08.03

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

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

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

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

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

26

2026.03.13

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号