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

typescript support #67

Closed
Guria opened this issue Mar 29, 2016 · 7 comments
Closed

typescript support #67

Guria opened this issue Mar 29, 2016 · 7 comments

Comments

@Guria
Copy link

Guria commented Mar 29, 2016

I wonder if typescript support is in the scope of this package.

It works well for transpiled stateless components, but can't recognize component transpiled from export class SomeStatefulComponent extends React.Component variant:

var SomeStatefulComponent = (function (_super) {
    __extends(SomeStatefulComponent, _super);
    function SomeStatefulComponent(props) {
        _super.call(this, props);
        this.state = {
            foo: 'bar',
        };
    }
    SomeStatefulComponent.prototype.render = function () {
        return react_1.createElement('div', {});
    };
    SomeStatefulComponent.defaultProps = {
        bar: 'baz'
    };
    return SomeStatefulComponent;
}(react_1.Component));
exports.SomeStatefulComponent = SomeStatefulComponent;

But it seems that generated d.ts files is much more great source to parse:

import { Component } from 'react';
export interface SomeStatefulComponentProps {
    /**
     * jsdoc
     */
    bar: string;
}
/**
 * jsdoc
 */
export declare class SomeStatefulComponent extends Component<SomeStatefulComponentProps, {
    foo: string;
}> {
    static defaultProps: {
        foo: string;
    };
    constructor(props: SomeStatefulComponentProps);
    render(): __React.ReactElement<{}>;
}
export default SomeStatefulComponent;
@fkling
Copy link
Member

fkling commented Mar 30, 2016

Yeah, react-docgen doesn't work with generated code. I don't think is there anything we can do about it, since generated / transpiled code can be quite arbitrary and have helpers that make analysis more difficult.

Regarding TypeScript: I don't think the libraries that react-docgen builds upon will be handle to deal with TypeScript. However, if there is a way to convert a TypeScript AST into an equivalent JavaScraipt / Babylon AST, I'm happy to look into it. That said, I could imagine that there already is a documentation generation tool for TypeScript which likely would work fine for your use case as well.

I'm closing this for now since I don't think there is anything else I can do here.

@fkling fkling closed this as completed Mar 30, 2016
@Guria
Copy link
Author

Guria commented Mar 31, 2016

Not sure if Typescript AST can be easy converted to Babylon one. Here is an example of parsing Typescript one: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API#traversing-the-ast-with-a-little-linter

@sapegin
Copy link
Contributor

sapegin commented Apr 16, 2017

react-docgen-typescript may be useful for some use cases.

@StJohn3D
Copy link

For anyone still finding this, I ended up going with documentalist - it parses typescript as well as markdown and similarly spits out splendid json. It's not built specifically for react components - which can be a good thing - so you'll need to write a little bit of logic to aggregate a component's data to it's props (it's really not that bad though. I might even share a gist when I'm done doing this myself.) So it's closer to something like typedoc - however it's JSON output is nicely documented and (IMHO) much easier to make sense of.

@sophieH29
Copy link

@StJohn3D Please, do share the gist!

@StJohn3D
Copy link

StJohn3D commented Nov 7, 2018

@sophieH29 so for my needs I ended up not aggregating the data as it allows me to be more flexible in my documentation workflow to just call a function and pass in the name of the export I'm looking for.

That said, when you run documentalist and inspect the json output you should find something like this.
Assuming an index.ts which exports the following:
export interface IMyClassProps ...
export class MyClass extends React.Component<IMyClassProps , IMyClassState>...

{
  "typescript": {
    "MyClass": {
      "kind": "class",
      "extends": [
        "Component<IMyClassProps, IMyClassState>"
      ],
    },
    "IMyClassProps": {
      "kind": "interface",
      "properties": [
        {
          "fileName": "src/myClass.tsx",
          "flags": {
            "isExported": true,
            "isExternal": false,
            "isOptional": true,
            "isPrivate": false,
            "isProtected": false,
            "isPublic": false,
            "isStatic": false
          },
          "kind": "property",
          "name": "headerText",
          "sourceUrl": "https://github.com/redacted/src/myClass.tsx#L7",
          "type": "undefined | string"
        }
      ]
    }
  }
}

There's actually WAY more data that you'll get than this but I'm highlighting the relevant bits for brevity.

With that json youtput you could use a regex to find each class' properties...
Assuming you import that json to a variable and then call the following function with that object.

const getData = (docs) => {
  const result = []
  for (key in docs.typescript) {
    const data = docs.typescript[key]
    if (data.kind === "class") {
      const propsInterfaceName = data.extends[0].match(extendsRegex)[1]
      const propsData = docs.typescript[propsInterfaceName]
      data.properties = propsData.properties
      result.push(data)
    }
  }
  return result
}

Obviously that function is not production ready - there's no error catching - it's just assuming everything will be there. But the point is to show how easy it would be to aggregate the data.

The output of that function would be an array of all of your exported classes. And each object in that array would also contain a propterties key with all of the aggregated props information from it's associated exported props interface.

Hope that helps!
For my purposes I'm using documentalist to parse both typescript and markdown.
In my markdown I just put comments for where I want to insert data. e.g. <!-- props IMyClassProps --> and then I've written custom regex patterns and logic to parse the markdown objects and replace those comments with the data from typescript. So it's not something easy to share and very specific to my repo but the examples above should help get the wheels turning :)

jsbin link

@sophieH29
Copy link

@StJohn3D thank you! I'll take a look on that

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants