-
Notifications
You must be signed in to change notification settings - Fork 258
Description
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!