Typescript: Support typedef inheritance with JSDoc

Created on 16 Nov 2017  ·  8Comments  ·  Source: microsoft/TypeScript

TypeScript Version: 2.7.0-dev.20171116

Code

/**
 * @typedef {Object} Base
 * @property {String} baseProp
 */

/**
 * @typedef {Base} Child
 * @property {String} childProp
 */

/** @type {Child} */
const child = { baseProp: '' };

Expected behavior: Error. child is missing the childProp property.

Actual behavior: No error. The Child type is identical to the Base type and only requires a baseProp property. The childProp property definition is completely ignored.

Or maybe there's another way to do the equivalent of interface Child extends Base here?

JSDoc In Discussion Suggestion

Most helpful comment

You can use an Intersection Type notation there:

/**
 * @typedef {Base & {childProp: String}} Child
 */

or

/**
 * @typedef {Object} ChildType
 * @property {String} childProp
 *
 * @typedef {Base & ChildType} Child
 */

should both work.

All 8 comments

For what it's worth, I also tried the following combinations. Both result in Child being typed as any.

/**
 * @typedef {Object} Child
 * @extends Base
 * @property {String} childProp
 */
/**
 * @typedef {Object} Child
 * @mixes Base
 * @property {String} childProp
 */

You can use an Intersection Type notation there:

/**
 * @typedef {Base & {childProp: String}} Child
 */

or

/**
 * @typedef {Object} ChildType
 * @property {String} childProp
 *
 * @typedef {Base & ChildType} Child
 */

should both work.

@ekulabuhov life saver!

Although the & trick works most of time.
Some things will only work with interface instead of type

// won't work, and no workaround at all

/**
 * @typedef {number|ArrayjOfValue} value
 */

/**
 * @typedef {Array<value>} ArrayjOfValue
 */

/**
 * @type {value}
 */
var k1 = [1, [1]]
// works

type value = number | ArrayOfValue;

interface ArrayOfValue extends Array<value> {}

var k1: value = [1, [1]]

The interface in typescript is lazy evaluated.
And only checked when the value is actually encountered.
So, it can work as a guard to prevent the definition from expanding infinitely.

While the type is not.
And will be expanded completely at init time.
Making referring to itself not possible at all.

I think typedef in JSDOC extends from non Object Object type should be translate to a interface instead of a type definition.

Or it will make the JSDOC syntax lack a bunch of ability

But I don't have any idea whether it will break existing code or not. And whether interface can be a superset of type or not.

For JSDoc code already using this, it'd be nice to have compatibility. Same for interface/implements....

(Pardon perhaps silly question regarding JSDoc behavior in current VSCode.)

"Intersection Type notation" from ekulabuhov's comment somewhat works in current VSCode but only when used like

/**
 * @typedef movable
 * @property {function} moveMe
 */
/**
 * @typedef {movable & HTMLElement} movableElement
 */
/** @type movableElement */
var myElement = document.querySelector('#myElement');
myElement.moveMe; // OK, function
myElement.tabIndex; // OK, number
myElement.error_test; // OK, does not exist

But straightforward declaration of custom type with base type and custom property

/**
 * @typedef {HTMLElement} movableElement
 * @property {function} moveMe
 */

results in simply aliasing HTMLElement as movableElement but with no added property. (It is basically what OP describes.) So is it a bug or some reasonable behavior? Using TypeScript (hopefully) equivalent

type movableElement = HTMLElement & { moveMe: Function };
var myElement: movableElement = document.querySelector('#myElement');
myElement.tabIndex; // OK, number
myElement.moveMe; // OK, Function
myElement.error_test; // OK, does not exist

works as expected.

BTW, if that Intersection Type notation is standard and stable already, it should be probably mentioned in https://github.com/Microsoft/TypeScript/wiki/JsDoc-support-in-JavaScript (?)

This would be really great as intersection types "&" are not going to to be supported by jsdoc.

Any valid @JSDoc solution yet?

Was this page helpful?
0 / 5 - 0 ratings