如何记录由扩展对象与其他属性组合而成的函数的返回?
Posted
技术标签:
【中文标题】如何记录由扩展对象与其他属性组合而成的函数的返回?【英文标题】:How to document the return of a function, that is made from combining a spread objects with other properties? 【发布时间】:2021-12-26 17:03:54 【问题描述】:我有代码可以传播返回的对象,并添加一个新属性
看起来像这样:
/**
* it does the things
* @param Object input object containing id and key
* @param Object.string id unique id to associate with return value
* @param Object.string key unique key used to get things
* @returns Object.<???, id:string> the returned things and id.
*/
const doTheThings = (id, key) =>
thingDoer(key).then(things =>
...things, // how do I document the properties of this
id // combining with this?
)
我目前在@returns
部分中有???
等于things: *
。但这看起来好像在返回中会有一个名为“things”的键,而实际上没有。
我如何记录things
是什么?如果 thingDoer
有自己的 JSDoc 我可以依靠,它会改变吗?最好不涉及打字稿。
【问题讨论】:
这里听起来很一般。你拿T
并返回它丰富。它总是添加相同的属性(things
)还是可以不同?
@VLAZ 除了 javascript 没有泛型。当您说“它总是添加...”时,您的意思是函数thingDoer
是否总是返回相同的things
?是的,它始终是相同的形状,但值可能会改变。
"除了 JavaScript 没有泛型" 但 JSDoc 有 ;) 即使它们没有很好的文档记录。 “是的,它始终是相同的形状,但值可能会改变。”那么也许泛型是矫枉过正。如果总是一样,也许你只需要@typedef
。
【参考方案1】:
它使用扩展语法的事实是无关紧要的。您记录功能做什么不一定如何。因此,它需要 一些 对象并(可能)使用更多属性来丰富它,以保持 id
就位。
/**
* @typedef Thingamajig
* @type object
* @property number foo - some number here
* @property string bar - a string used for something
*/
/**
* Transforms things.
* @param string key - what to transform
* @return Promise<Thingamajig> - transforms into this
*/
function thingDoer(key) /* .... */
/**
* it does the things
* @param Object input - object containing id and key
* @param string input.id - unique id to associate with return value
* @param string input.key - unique key used to get things
* @returns Promise<Thingamajig & id:string> the returned things and id.
*/
const doTheThings = (id, key) =>
thingDoer(key).then(things =>
...things,
id
)
See on the TypeScript Playground - 文件类型已设置为 JavaScript(可在 TS 选项 下找到),因此这纯粹是演示如何解释 JSDoc 的一种方式。将鼠标悬停在函数和参数上以查看它们的类型。
这里的关键是使用@typedef
声明thingDoer
返回和doTheThings
也使用的相同对象结构。这样,如果它改变了,你只改变一个地方。
doTheThings
函数然后返回 Thingamajig & id:string
,这是一个 Thingamajig
,并添加了一个字符串 id
属性。另一种方法是创建另一个 typedef,如 ThingamajigWithId
并在那里记录属性。取决于使用 JSDoc 的工具。
/**
* @typedef ThingamajigWithId
* @type object
* @property number foo - some number here
* @property string bar - a string used for something
* @property string id - unique identifier.
*/
您可以使用an intersection (the &
) 做的一件有趣的事情是分别使用 ID 声明类型,然后将两者相交。这样您就可以记录它:
/**
* @typedef Thingamajig
* @type object
* @property number foo - some number here
* @property string bar - a string used for something
*/
/**
* @typedef WithId
* @type object
* @property string id - unique identifier
*/
/** ...
* @returns Promise<Thingamajig & WithId> the returned things and id.
*/
See on the TypeScript Playground
请注意,类型交集不是 JSDoc 本身的一部分。它们是 TypeScript 的一项功能。根据使用 JSDoc 的工具,它可能会或可能不会起作用。例如,Visual Studio Code 可能不会抱怨,但是,如果您有一个从注释构造文档的工具,它可能无法将 &
识别为有效。
另请注意,在 JSDoc 本身中添加这种类型的对象扩展是一个长期存在的功能:
Issue on GitHub 自 2016 年 4 月起 关于引发它的 Stack Overflow 的问题:How to extend a typedef parameter in JSDOC?
目前似乎没有一种方法可以扩展满足所有 JSDoc 使用者的 typedef。唯一似乎保证可以工作的事情是手动创建一个 typedef 手动重复所有属性(我在上面展示过):
/**
* @typedef ThingamajigWithId
* @type object
* @property number foo - some number here
* @property string bar - a string used for something
* @property string id - unique identifier.
*/
然而,Thingamajig
的基本 typedef 并没有改变,这使得维护起来很烦人。以下是可能支持的不同内容的简要概述
&
。
一些工具似乎支持使用 |
代替,并且会显示 A | B
具有来自 A
和 B
的两个属性,即使它应该是一个替代。
一些工具可以识别
/**
* @typedef A, B Combined
*/
一些工具可以识别
/**
* @typedef Combined
* @type A, B
*/
我找不到一种似乎在任何地方都能始终如一地工作的技术。
【讨论】:
以上是关于如何记录由扩展对象与其他属性组合而成的函数的返回?的主要内容,如果未能解决你的问题,请参考以下文章
编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成