jsdoc:用模板扩展类型(用泛型扩展类型)

Ale*_*rff 6 jsdoc webstorm

例子:

基础类型:

/**
 * @typedef {Object} LabelValue
 * @template T
 * @property {String} label
 * @property {T} value
 */
Run Code Online (Sandbox Code Playgroud)

可以很好地用作

/** @type {LabelValue<SomeType>} */

我想像这样扩展这个基本类型(也许这只是错误的语法,我不确定):

/**
 * @typedef {LabelValue<T>} LabelValueExtended
 * @template T
 * @property {String} extensionProp
 */
Run Code Online (Sandbox Code Playgroud)

我使用 webstorm 并且它没有根据这样使用的类型向我显示任何建议:

/** @type {LabelValueExtended<SomeType>} */

此变体也不会触发来自 webstorm 的任何建议:

/**
 * @typedef {LabelValue} LabelValueExtended
 * @template T
 * @property {String} label
 * @property {T} value
 * @property {String} extensionProp
 */
Run Code Online (Sandbox Code Playgroud)

但只有当我用Object模板之类的常见类型替换我的自定义类型时才能正常工作。例如这有效:

/**
 * @typedef {Object} LabelValueExtended
 * @template T
 * @property {String} label
 * @property {T} value
 * @property {String} extensionProp
 */
Run Code Online (Sandbox Code Playgroud)

我的第一个 Base 类型示例也很好用,因为它扩展了普通Object类型。但是如果我做一些虚拟的事情,例如

/**
 * @typedef {Object} Dummy
 * @property {String} dummy
 */

/**
 * @typedef {Dummy} LabelValue
 * @template T
 * @property {String} label
 * @property {T} value
 */
Run Code Online (Sandbox Code Playgroud)

它还破坏了来自 webstorm 的任何属性建议。

没有模板的类型工作正常。例如

/**
 * @typedef {Object} Dummy
 * @property {String} dummy
 */

/**
 * @typedef {Dummy} LabelValue
 * @property {String} label
 * @property {*} value
 */
Run Code Online (Sandbox Code Playgroud)

如果像这样使用: /** @type {LabelValue} */,那么 webstorm 会正确建议两种类型的道具,但显然我不会得到任何关于value财产的建议。

问题是:我是否对带有模板的 jsdoc 使用了不正确的语法(请建议有效的)或 webstorm 只是处理错误?

dea*_*anN 1

我使用rider(JetBrains的另一个产品,与WebStrom相同)对我来说,最有效的方法是这样的:(虽然它并不完全没有错误,所以请读到最后)

/**
 * @typedef LabelValueExtended
 * @extends {LabelValue<T>}
 * @template T
 */
Run Code Online (Sandbox Code Playgroud)

虽然我的情况更像是这样:

/**
 * @typedef module:invoice.PurchaseOrderWithInvoicePaymentTermItemsResponseDto
 * @extends {BaseInvoiceWithInvoicePaymentTermItemsResponseDto<module:invoice.PurchaseOrderResponse>}
 */
Run Code Online (Sandbox Code Playgroud)

定义后(缺点和优点在评论中提到

/** @type {module:invoice.PurchaseOrderWithInvoicePaymentTermItemsResponseDto} */
var x={};
// [Keyboard combination based on Resharper key map]
x. // [Ctrl+Space] Here I get no suggestion from IDE
x. // [Ctrl+Q] it doesn't give me direct suggestion either
// invoice is defined in `BaseInvoiceWithInvoicePaymentTermItemsResponseDto`, and it is generic of type `PurchaseOrderResponse`
x.invoice //it just points to the base type, not the derived type
x.invoice //[Ctrl+Q] HERE it gives me the derived type | it means my mapping work, but its rider unable to render it properly in other places
Run Code Online (Sandbox Code Playgroud)

关于评论

图片1:

  1. 它知道基本类型
  2. 它无法列出该属性,因为它列出了已知类型的内容
  3. 它无法加载正确的派生类型

2022-Rider JSDoc 扩展类型用法、属性列表 图片2:

  1. 它仍然没有检测到该类,只是索引表明它存在于某些地方

2022-Rider JSDoc 扩展类型用法,在对象外部的特定属性上

图3:

  1. 如果您使用文档对话框(对于 resharper 键映射 Ctrl+Q),并在引用的对象内定义属性(无需再次指定类型),它可以为属性类型提供正确的描述

2022-Rider JSDoc 扩展类型用法,对象内的特定属性

图4:

  1. 在对象内部定义属性后,它也可以将文档带出外部,但在将属性放入该对象之前,它不会在一秒钟前这样做

2022-Rider JSDoc 扩展类型用法,在对象外部的特定属性上,并在对象内部的某处拥有该属性

图5:

  1. 当涉及到子属性时,它又搞砸了

2022-Rider JSDoc 扩展类型用法,尝试在对象外部列出子属性并将属性放在对象内部的某处

其他扩展方法

人们还提到了其他扩展方法,我也尝试过,但没有深入研究:

为了更好地理解,我删除了该模块并将名称更改为 A 和 B

根据

/** @typedef A
 * @template T
 * @property ...
   ...       ...
   ...       ...
 */
Run Code Online (Sandbox Code Playgroud)
  1. 目前已解释
/**
 * @typedef B
 * @extends {A<MyType>}
 */
Run Code Online (Sandbox Code Playgroud)
/**
 * @typedef {A<MyType>} B
 */
Run Code Online (Sandbox Code Playgroud)
/**
 * @typedef B
 * @type {A<MyType>}
 */
Run Code Online (Sandbox Code Playgroud)
  1. 注意:我发现的文章使用了带有small的对象o,但是rider给了我错误,所以我将其更改为CapitalO
/**
 * @typedef B
 * @type {Object.<A<MyType>>}
 */
Run Code Online (Sandbox Code Playgroud)

结论

似乎最好重新定义所有类型,但不要依赖 JSDoc 扩展,因为没有 IDE 创建者给予它如此深入的信任,即使不同的 IDE 有自己的偏好,例如有些这样做:其他这样@property {type} x - description@property x {type} description,等等,并且在解析这种语言时它们之间没有强契约