Repository: styleguidist/react-docgen-typescript (ts)

Issue:
expression returned using shouldIncludeExpression is not the original root expression
When an expression is returned it might be the typeSymbol https://github.com/styleguidist/react-docgen-typescript/blob/1a14c0edc609455a4c2766fa5eec68bc3b902d05/src/parser.ts#L304 which means that we cannot easily get the original root expression from it. Was this intended? I think it would be a lot more powerful if the original root expression was returned which would allow users to pull as much information as needed out of it.

My primary use case for this would be to be able to get default export names using it, which I cannot see an easy way to get this information from the type symbol which refers to the "FunctionComponent" type.

cc @TrevorBurnham

Pull request description:
feat: Export raw expression when shouldIncludeExpression is set
Resolves #432 cc @joshwooding

This PR adds a property called `rawExpression` to the parsed object when `shouldIncludeExpression` is set, in addition to the existing `expression` property. The two are identical in many cases, but diverge when the exported component has a wrapper such as `React.memo`. Example from the test cases:

```ts
// parsed.expression
function Jumbotron(props: JumbotronProps) {
  return <div>Test</div>;
}

// parsed.rawExpression
export default React.memo(Jumbotron);
```

Exporting both will allow developers to extract additional information from the raw expression when necessary.

Patch:
diff --git a/src/parser.ts b/src/parser.ts
index 0d08489..47a86e5 100644
--- a/src/parser.ts
+++ b/src/parser.ts
@@ -15,6 +15,7 @@ export interface StringIndexedObject<T> {
 
 export interface ComponentDoc {
   expression?: ts.Symbol;
+  rootExpression?: ts.Symbol;
   displayName: string;
   filePath: string;
   description: string;
@@ -395,6 +396,7 @@ export class Parser {
 
     if (result !== null && this.shouldIncludeExpression) {
       result.expression = rootExp;
+      result.rootExpression = exp;
     }
 
     return result;


Test patch:
diff --git a/src/__tests__/parser.ts b/src/__tests__/parser.ts
index fc9c178..fab7b73 100644
--- a/src/__tests__/parser.ts
+++ b/src/__tests__/parser.ts
@@ -1513,6 +1513,7 @@ describe('parser', () => {
       it('should be disabled by default', () => {
         const [parsed] = parse(fixturePath('StatelessDisplayName'));
         assert.equal(parsed.expression, undefined);
+        assert.equal(parsed.expression, parsed.rootExpression);
       });
 
       it('should cause the parser to return the component expression when set to true', () => {
@@ -1520,6 +1521,18 @@ describe('parser', () => {
           shouldIncludeExpression: true
         });
         assert.equal(parsed.expression!.name, 'Stateless');
+        assert.equal(parsed.expression, parsed.rootExpression);
+      });
+
+      it('should cause the parser to return the root expression when set to true', () => {
+        const [parsed] = parse(
+          fixturePath('FunctionDeclarationAsDefaultExportWithMemo'),
+          {
+            shouldIncludeExpression: true
+          }
+        );
+        assert.equal(parsed.expression!.name, 'Jumbotron');
+        assert.equal(parsed.rootExpression!.name, 'default');
       });
     });
   });