reactjs / reactjs/react-docgen

Mo support for typescript intersection and parenthesized types

Open
#914 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
3.8k
Forks
316
Avg merge
5h 7m
Merged PRs (30d)
4

Description

I wish this project would just use typescript to parse typescript as the old project react-docgen-typescript did. Why? Because we try to upgrade our design-system to use this new package "react-docgen" but we're already missing some core features.

A union type definition like the following is not parsed correctly:

type ButtonVariant = "standard" | "primary";

type ButtonWithChildren = {
  children: ReactNode;
  icon?: ReactNode;
};

type ButtonWithIconOnly = {
  children?: never;
  icon: ReactNode;
};

export type ButtonProps = {
  className?: string;
  variant?: ButtonVariant;
} & (ButtonWithChildren | ButtonWithIconOnly);

export const RegularFunctionComponent: FunctionComponent<ButtonProps> = (
  props,
) => <div>Just a regular component</div>;

Result

{
  "RegularFunctionComponent": {
    "description": "",
    "displayName": "RegularFunctionComponent",
    "methods": [],
    "props": {
      "className": {
        "required": false,
        "tsType": {
          "name": "string"
        },
        "description": ""
      },
      "variant": {
        "required": false,
        "tsType": {
          "name": "union",
          "raw": "\"standard\" | \"primary\"",
          "elements": [
            {
              "name": "literal",
              "value": "\"standard\""
            },
            {
              "name": "literal",
              "value": "\"primary\""
            }
          ]
        },
        "description": ""
      }
    },
    "path": "blocks/styled-resolver/test/testComponents.tsx"
  }
}

The two props "children" and "icon" are missing in the result. Parsing the same thing with react-docgen-typescript would indeed find the two props, so i would expect the following output:

Expected

{
  "RegularFunctionComponent": {
    "description": "",
    "displayName": "RegularFunctionComponent",
    "methods": [],
    "props": {
      "children": {
        "required": false,
        "tsType": {
          "name": "ReactNode"
        },
        "description": ""
      },
      "icon": {
        "required": false,
        "tsType": {
          "name": "ReactNode"
        },
        "description": ""
      },
      "className": {
        "required": false,
        "tsType": {
          "name": "string"
        },
        "description": ""
      },
      "variant": {
        "required": false,
        "tsType": {
          "name": "union",
          "raw": "\"standard\" | \"primary\"",
          "elements": [
            {
              "name": "literal",
              "value": "\"standard\""
            },
            {
              "name": "literal",
              "value": "\"primary\""
            }
          ]
        },
        "description": ""
      }
    },
    "path": "blocks/styled-resolver/test/testComponents.tsx"
  }
}

But i'm also wondering why the official babel parser typescript plugin can't handle that case?

Update: A short test with babel parser itselfs shows me that babel indeed is parsing this case correctly and all information would be available to produce the expected result. It is just not implemented in this package.

Update 2: I'm working on a PR and it seems to be quite promising - the complex intersection case with multiple interfaces is working now, i had to modify the "handleTSIntersectionType" function and add the missing "handleTSParenthesizedType". Now only the types are getting in my way and i destroyed some existing cases with intersection.... still working on it, hopefully next week i can present a fix :)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with handleTSIntersectionType and the missing handleTSParenthesizedType mentioned in the issue, using blocks/styled-resolver/test/testComponents.tsx as the reproduction case. Compare the generated props with the expected output, then verify that children and icon are extracted without breaking existing intersection cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
babel, typescript
Domain
documentation
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.