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 JSDoc @property on JavaScript class declarations #39729

Closed
miyasudokoro opened this issue Jul 24, 2020 · 2 comments
Closed

Support JSDoc @property on JavaScript class declarations #39729

miyasudokoro opened this issue Jul 24, 2020 · 2 comments

Comments

@miyasudokoro
Copy link

miyasudokoro commented Jul 24, 2020

Search Terms JSDoc @Property

Suggestion

Just as you support @property for the @typedef declaration, please also support @property for @class/@constructs (etc.) declarations. My preference would be that it should work exactly as the @typedef one does, only applied to actual code objects rather than phantom ones.

Use Cases

  • When using Object.defineProperties to define properties that, for example, follow a dynamic naming convention and are not explicitly named.
  • When creating Proxy objects that trap the getPrototypeOf value and therefore have a type assigned.

Examples

The use case that prompted this request is a pure-JS factory file that creates a Proxy instance. (I have simplified this example a lot; I am actually using a factory pattern rather than the constructor, but this is easier to read and still works.) The problem is, to document what properties are available via the proxy, I cannot currently do this obvious syntax, which is valid JSDoc syntax:

/** @class MyClass
 * @property email {string} The user's email
 * @property name {string} The user's name
 */
class MyClass {
    constructor( target ) {
        return new Proxy( target, proxyHandler );
    }
}
const proxyHandler = {
    // lots of stuff here
    getPrototypeOf: () => MyClass.prototype // this is how it will later be instanceof MyClass
}

// ... later in another file ...
import MyClass from './MyClass.js';

/** @param {MyClass|OtherClass} the data
 */
getUserEmail( myInstance ) {
    if ( myInstance instanceof MyClass ) {
        return myInstance.email;
    }
}

As you can see in the example function, I could certainly use @typedef to declare MyClass in order to get the @param {MyClass} part to work, but I could not also use instanceof with the same symbol.

The way I got it working for TypeScript was like this, which is annoyingly verbose. In my actual case, it takes more than 100 lines of code just to declare all the properties.

/** @class MyClass
 */
class MyClass {
    constructor( target ) {
        /** The user's email.
         * @type {string}
         */
        this.email = undefined;

        /** The user's name.
         * @type {string}
         */
        this.name = undefined;

        return new Proxy( target, proxyHandler );
    }
}
const proxyHandler = {
    // lots of stuff here
    getPrototypeOf: () => MyClass.prototype // this is how it will later be instanceof MyClass
}

Checklist

My suggestion meets these guidelines:

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

ExE-Boss commented Jul 27, 2020

Duplicate of #26811

@miyasudokoro
Copy link
Author

I'll close because it is a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants