Reputation: 773
Here is how you define a custom type, from the Closure compiler documentation:
/**
* @typedef {{
* foo:string,
* bar:number,
* foobar: (number|string)
* }}
*/
var Mytype;
How do I add comments to explain what each property does, preferably on the same line as each property?
Upvotes: 0
Views: 25
Reputation: 18331
A @typedef
can certainly be used this way, but consider a @record
instead - and if needed, @typedef
the record to another name. You can add more remarks in the jsdoc block you've written already, but not specifically for each member.
What you've built here is an anonymous structural type, and then used typedef to give it a (new) name. Specifically, this is a record type when defined using this "object literal" syntax.
Instead, consider defining an explicit type, such as with @record
, allowing you to add more remarks :
/**
* A short note about what this structural interface is for.
* @record
*/
function Mytype() {}
/**
* A string, used for foo things.
* @type {string}
*/
Mytype.prototype.foo;
/**
* The number of a bar, or something.
* @type {number}
*/
Mytype.prototype.bar;
/**
* A field with a union type
* @type {number|string}
*/
Mytype.prototype.foobar;
Be aware that structural types can have implications on the rest of your program - it may be beneficial to define a nominal type (e.g. a class with a constructor) to give the compiler more knowledge and control over what the code can be allowed to do. Simply changing the above to be declared as an @interface
or using a @constructor
(possibly as an es5 class) will be enough to declare such a type - but then you must use it, instead of passing object literals. It will have the advantage of avoiding permitting the compiler to consider two unrelated types (where has a subset of the fields of the other) as being related, and thus allowing the "wrong" type to be substituted. Beyond allowing "the wrong type" to be passed, it also prevents some optimizations from being applied. Simple example: if one type is never directly instantiated, uses of that type can always be marked as null, but if a subtype apparently exists and is used, then those usages can't be optimized out.
Upvotes: 1