Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for JSDoc interface definition #33207

Open
5 tasks done
stof opened this issue Sep 3, 2019 · 7 comments
Open
5 tasks done

Support for JSDoc interface definition #33207

stof opened this issue Sep 3, 2019 · 7 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@stof
Copy link

stof commented Sep 3, 2019

Search Terms

jsdoc, interface
I found #16142 which was closed by the reporter, and never reopened even though some other people suggested it.

Suggestion

JSDoc has a way to declare interfaces, through @interface, @function (and then @implements on the class). It would be great if tsc could support them (defining a TS interface based on that info).

Use Cases

JSDoc interfaces are useful to define interfaces implemented by multiple classes, that are then used based on this interface. This is part of JSDoc, but currently unsupported by tsc.

Examples

/**
 * @interface Metric
 */
/**
 * @function
 * @name Metric#getName
 * @returns {string}
 */
/**
 * @function
 * @name Metric#compute
 * @param context
 * @param [extra]
 * @returns {Promise<object>}
 */

/**
 * @constructor
 * @implements {Metric}
 */
function ActivityScoreMetric () {
    // [REDACTED]
}
ActivityScoreMetric.prototype = {
  compute: function (context, extra) {
      // [REDACTED]
  },

  getName: function () {
    return 'activity_score'
  }
}

// Other implementations go there

// Later code deals with `Array<Metric>` for some variables

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@sandersn
Copy link
Member

sandersn commented Sep 3, 2019

This is a sub-issue of #30624. Right now we have decided not to make all of Typescript's features available in JSDoc. Writing 40 lines of metadata in a comment is not much different from putting those same lines in a d.ts file, and we believe the d.ts syntax is much more readable to humans.

@sandersn sandersn added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Sep 3, 2019
@stof
Copy link
Author

stof commented Sep 4, 2019

@sandersn I tend to agree that the syntax of TS is more readable. But here, I'm not asking to support TS syntax inside JSDoc (which is what I understand from #30624) but to support existing JSDoc features (so that code already using them in JSDoc can be understood by the TS compiler). This is an existing JSDoc syntax for interface (and yes, again, I totally agree that it is lot less readable that the TS syntax).

@sandersn
Copy link
Member

sandersn commented Sep 4, 2019

I looked for uses of @interface and @implements by grepping around the dependencies of our user tests. It's a good cross-section of JS code. It doesn't look like anybody uses @interface the way jsdoc suggests, although I found a few that use it the way that Closure does.

Until we have evidence that people use @interface the way jsdoc suggests, there's no reason for us to support it.

react-dom

Uses @implements for PooledClass, which is a declared as a var with no jsdoc.

Uses @interface as a jsdoc on object literals. It's always a reference to what appears to be a superclass, so I think they're using it to mean @extends.

superagent

Uses @implements ReadableStream, but doesn't define that interface anywhere.

ejs

Same as superagent, except with Cache, EscapeCallback, RethrowCallback

nise and sinon

Uses @interface on a class with no implementation:

  /** @interface */
  function Encoder() {}
  Encoder.prototype = {
    handler: function(stream, code_point) {}
  };

I'm pretty sure this is how closure defines interfaces. chrome-devtools-frontend, firebase and protobufjs also work this way. These are all google projects, so it's not surprising.

@stof
Copy link
Author

stof commented Dec 9, 2019

Uses @implements ReadableStream, but doesn't define that interface anywhere.

isn't ReadableStream defined in the nodejs types ?

@TimvdLippe
Copy link
Contributor

We use @interface extensively in Chrome DevTools and the lack of support with checkJs means we can not use TypeScript to check our JavaScript. Our usage: https://cs.chromium.org/search/?q=f:devtools-frontend+@interface&sq=package:chromium&type=cs

I am not sure if we can use the .d.ts trick, as TS itself complains about how classes annotated with @interface are defined (it complains about missing return statements for example)

@sandersn
Copy link
Member

@TimvdLippe Could you open a separate issue for supporting closure's @interface? It has (1) a different audience (2) different requirements (3) different implementation. Having a separate issue is useful for (1), since we use upvotes as data for prioritising features. But d.ts-based workarounds are different too; I'd like to know what you've tried so far and what Typescript errors you're getting.

@benmccann
Copy link
Contributor

We use @interface in Chart.js. For example to document our plugin interface: https://github.com/chartjs/Chart.js/blob/771fe520957199b32a26205c14f4816002842bcb/src/core/core.plugins.js#L173

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants