5

I have a javascript function that returns a constructor (see code sample below). How would I document this with the @returns tag of jsdoc. It doesnt seem correct to do @returns {MyConstructor} because that implies I am returning an instance of "MyConstructor" rather than the constructor itself, right?

function MyConstructor() {
    var self = this;

    self.myFunction = function() {
        return true;
    };

    self.getMyFunctionResult = function() {
        return self.myFunction();
    };
}

/**
 * @returns {?} A constructor that will be instantiated
 */
function getConstructor() {
    return MyConstructor;
}

var constructor = getConstructor();
var instance = new constructor();
computrius
  • 690
  • 7
  • 16
  • Why would you want to return a constructor. Seems like you're doing pointless things just like the use of `self` at the top... – marekful Jan 08 '14 at 17:24
  • 1
    I have a reason that is not apparent in the example above that is a bit complicated to explain. But it isn't relevant or necessary to be able to answer the question. – computrius Jan 08 '14 at 17:25
  • So what about `@returns MyConstructor`? – marekful Jan 08 '14 at 17:26
  • 2
    From the question: " It doesnt seem correct to do @returns {MyConstructor} because that implies I am returning an instance of "MyConstructor" rather than the constructor itself, right?" – computrius Jan 08 '14 at 17:27
  • `@returns a reference to MyConstructor` vs `@returns an instance of MyConstructor` – marekful Jan 08 '14 at 17:29
  • 1
    Yeah, I could say that in the description, but I was more looking for if there was a proper way to indicate that as the data type. – computrius Jan 08 '14 at 17:30
  • Ps. the "var self" isnt really needed in this example. It is just there for completeness. It becomes needed as the definition of "this" changes inside of the member functions (for example, if I need to call a second public method from inside of another public method). – computrius Jan 08 '14 at 17:33
  • For anyone that thinks this is useless, there is an example, Sequelize models. The `init` method can be overriden, that will always return the class itself. Another example is fluent static classes – Maxwell s.c Dec 30 '19 at 21:41

4 Answers4

3

I do not think there is a way to use the brackets after @returns to document returning a specific instance. What goes in the brackets is interpreted as a type, always. This being said, there's a way to document that a specific instance of a type is being returned, by documenting the instance and using a link to the instance. I've shortened the code in the question to the essentials necessary to illustrate:

/**
 * @class
 */
function MyConstructor() {

}

/**
 * @returns {Function} A constructor that will be instantiated. Always
 * returns {@link MyConstructor}.
 */
function getConstructor() {
    return MyConstructor;
}

It can also be done with other things than classes:

/**
 * @public
 */
var foo = 1;

/**
 * @returns {number} {@link foo}.
 */
function getFoo(){
    return foo;
}

As far as I know, this is as good as it gets with jsdoc 3.

Louis
  • 146,715
  • 28
  • 274
  • 320
3

Maybe little bit late, but I have problem to find proper answer for your question event today.

When I try generate JSDoc automatically on WebStorm, this is what I get:

class Test {}

/**
 *
 * @return {Test}
 * @constructor
 */
function getTestConstructor() {
    return Test;
}

Return type definition is still strange, but constructor annotation may fulfill the purpose.

TonyB
  • 423
  • 4
  • 10
2

You can check the types returned by your functions using:

console.log(typeof constructor, typeof instance); // function object

In the documentation it says:

/**
 * Returns the sum of a and b
 * @param {Number} a
 * @param {Number} b
 * @returns {Number} Sum of a and b
 */
function sum(a, b) {
    return a + b;
}

http://usejsdoc.org/tags-returns.html

So in you example it would be:

/**
 * Returns the MyConstructor class
 * @returns {Function} MyConstructor class
 */
function getConstructor() {
    return MyConstructor;
}

Or if you are creating an instance of an Item:

/**
 * Returns an instance of the MyConstructor class
 * @returns {Object} MyConstructor instance
 */
function getInstance() {
    return new MyConstructor();
}
Kim T
  • 5,770
  • 1
  • 52
  • 79
  • So what if I wanted to be more specific about "Function"? Just "Function" alone isnt really useful documentation; it doesnt tell me anything. Would something like "@returns {Function} blaa" be valid? – computrius Jan 08 '14 at 18:07
  • If you have defined the function as a class: http://usejsdoc.org/tags-classdesc.html then you can declare the type as a class: http://usejsdoc.org/tags-type.html – Kim T Jan 08 '14 at 18:11
  • This only tells that the return is an function. Doesn't tell what class its returned. – Maxwell s.c Dec 30 '19 at 21:35
0

you can use:

@returns {new () => MyConstructor}

This turns the return object into an anonymous constructor which creates the MyConstructor type.

you can combine this with & pretty flexibly to shape how the constructor looks (if you have static methods you want access to) as well as what the constructor creates (if you have partials that you're putting together in a factory)

David Torrey
  • 1,335
  • 3
  • 20
  • 43