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

Allow @param to be enhanced by TypeScript #177

Open
SirDarquan opened this issue Apr 28, 2016 · 0 comments
Open

Allow @param to be enhanced by TypeScript #177

SirDarquan opened this issue Apr 28, 2016 · 0 comments

Comments

@SirDarquan
Copy link

The promise of TypeScript in Dgeni is that we won't need to redefine metadata about our code for commenting purposes and method parameters are no exception. Here's an example of our current situation:

/**
  * Here's a description about the member
  * @param {string} myParam - Here's a description about the myParam parameter
  */
public myMethod(myParam: string){...}

TypeScript knows that myParam is of type string but in order for my documentation to know that, I had to tell it, which sux. It would be nice if the param tag would automatically enhance itself with the type information. Fortunately, I've already figured out how to do this but the way to get it in place was weird.

var catharsis = require('catharsis');

module.exports = function associateTypeTransform() {
    return function (doc, tag, value) {
        if (tag.name && doc.parameters && !tag.type) {
            var tsParamInfo = doc.parameters.filter(function (paramData) {
                return paramData.startsWith(tag.name);
            })[0];

            var parts = tsParamInfo.split(':');
            if (parts.length == 2) {
                tag.typeExpression = parts[1].trim();
                tag.type = catharsis.parse("{" + parts[1].trim() + "}", { jsdoc: true });
                parts[0].endsWith('?') && (tag.optional = true);
            }
        }
        return value;
    }
}

To actually attach it to the param tagDef, I added this to my module definition:

    .config(function(parseTagsProcessor, associateTypeTransform){
                // is there an easier way to retrieve a tagDefinition?
        var parsing = parseTagsProcessor.tagDefinitions.filter(function(parser){
            return parser.name == "param";
        });
        parsing[0].transforms.push(associateTypeTransform);     
    })

This may not be the prettiest code but it does the job. Basically, this is a new filter that is run sometime after the extractType and extractName filters are run. The TypeScript parser places the extracted parameters in a property called parameters on the doc. Unfortunately, it's one string with the declaration in it as-is like so: "myParam: string". Anyway, the code makes sure that name has already been extracted and that there is no type information on the tag and that TypeScript already put the parameters property on the doc.

Once the tag qualifies for enhancement, it uses the name to look up the parameter and splits the declaration on the semicolon. Since Typescript types are optional, we do a check to see if it was declared. If it was we do the same thing the param tagDef does to create the type and typeExpression properties.

On a side note, TypeScript is able to infer variable types but I couldn't figure out where to look for that. It would be cool to have even if a type wasn't declared. With this in place and the insertion code done, the example above could now look like this:

/**
  * Here's a description about the member
  * @param myParam - Here's a description about the myParam parameter
  */
public myMethod(myParam: string){...}

Is it a huge savings? Not for just one parameter but when you think about how many parameters we create in code, it becomes significant. But more importantly, it ensures consistency between the code and documentation. Change the type and the documentation automatically is updated. And That makes it worth it. I would love for this to become a permanent part of jsdoc so everyone can just benefit.

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

1 participant