Skip to content

Intersection types are not documented #158

@kuzhelov

Description

@kuzhelov

Let me, please, start with a words of sincere appreciation of the work you are doing 👍 💯

Issue

react-docgen-typescript is unable to parse TS intersection types: https://www.typescriptlang.org/docs/handbook/advanced-types.html#intersection-types

Case

We are using react-docgen-typescript in our React components library (Stardust, https://github.com/stardust-ui/react), where we are going to export its components with the following type:

type ExtendedSFC<P> = React.SFC<P> & { create: TFactoryMethod }

In other words, we would like to extend React.SFC to support factory method (create).

This is a component's file example with minimal code necessary to simulate our case and repro this problem:

type ExtendedSFC<P> = React.SFC<P> & { create: () => void }

/**
 * This Foo description should be parsed.
 */
const Foo: ExtendedSFC<{}> = null    // sloppy, but just to simplify example's code

export default Foo

If this will be run through the parser of react-docgen-typescript (further will refer to it by just 'parser'), the actual result will be an empty array: [], while expected result will be a successful parse.

Workaround?

The following move will make parse to succeed, but there won't be any text captured as a description in the result:

interface ExtendedSFC<P> extends React.SFC<P> {
  create: () => void
}

/**
 * This Foo description should be parsed.
 */
const Foo: ExtendedSFC<{}> = null

export default Foo

and (unexpected to client) result is:

[ 
  { description: '',  // no description
    displayName: 'ExtendedSFC',  // display name is 'improperly' captured!
    methods: [],
    props: {} 
  } 
]

Root Cause

The cause of the problem is in the following lines of parser.js:

Parser.prototype.getComponentInfo = function (exp, source, componentNameResolver) {
        ...
        if (!exp.valueDeclaration) {

             // here, in case of INTERSECTION type used, it will be type.types and no type.symbol
            // - where 'types' prop will contain collection of all parsed types in intersection
            if (!type.symbol) {  
                return null;
            }
        ...

Proposed Solution Areas

Fetch symbol using types property of type object

Quite reasonable approach to handle this situation could be to introduce additional logic that will search for necessary symbols in type.types as well. This should produce the result client would expect here.

Provide necessary customisation point to client

This suggestion is about exposing all the necessary customisation means to the client, similar to how it is done for component name resolution logic:

// new member of parserOptions
componentTypeResolver: ...

Further Steps

Please, let me know if you do see this issue being fixed (and agree on the proposed approaches to do that / maybe introduce better way for doing that) - and I will be glad to help with the PR and all the necessary tests, as this issue is currently blocking for us.

Once again, thanks a lot for your efforts and this awesome docs generator you've built for Typescript!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions