strothj / react-docgen-typescript-loader

Webpack loader to generate docgen information from Typescript React components.
Other
360 stars 47 forks source link

Failure to describe props defined externally (without a corresponding component) #101

Open daniel-ac-martin opened 4 years ago

daniel-ac-martin commented 4 years ago

Note: This may be an inherited limitation of react-docgen-typescript.

Consider a project with the following files:

// MyComponent.tsx
import { CommonProps } from './common';

export type MyComponentProps = CommonProps & {
  /** Description for myProp */
  myProps?: string
};

export const MyComponent = (props: MyComponentProps) => null;
// common.ts
export type CommonProps = {
  /** Description for common prop */
  common?: string
};

Naively, one would expect the common prop to be properly documented on MyComponent and whilst the common prop does appear the docgen description is NOT included.

However, it is possible to coax the loader into the expected behaviour by defining a 'fake' component alongside the CommonProps. e.g.

// common.ts
export type CommonProps = {
  /** Description for common prop */
  common?: string
};

// WORKAROUND: An otherwise pointless component in order to coax react-docgen-typescript-loader
const StandardComponent = (props: StandardProps) => null;

I suspect this will be a limitation of the underlying react-docgen-typescript library but I've not delved deep enough into the issue to know for sure or to know if there is a nice way to fix this.

daniel-ac-martin commented 4 years ago

There seems to be an additional limitation (even with the workaround in place) in that when the webpack compiler is in watch mode changes to the CommonProps, docgen or typescript, do NOT cause the props description on MyComponent to be updated.

This is because the props information is stored on the component as a constant and as only the modified file is re-processed by the loader this constant is not updated.

I'd imagine the only way to fix this is for the props information to come via a function rather than a constant. (And perhaps said function could pull information out of the updated module.)