Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generics are being removed from JSX Elements #572

Open
csandman opened this issue Oct 12, 2023 · 2 comments
Open

Generics are being removed from JSX Elements #572

csandman opened this issue Oct 12, 2023 · 2 comments

Comments

@csandman
Copy link

I'm not sure if this is a bug or if I'm just doing something wrong, but recently I've been trying to write my first codemod script for my own NPM package chakra-react-select, which is a React component written in TypeScript. The goal is just to remove one prop/attribute from all instances of my component if it is present, as that prop is being deprecated. I have written a transformation that functions exactly as I'd expect, except my component has some optional generic types that are also being removed.

I have written the following to try and remove that prop:

import type { API, FileInfo } from "jscodeshift";

export default function transformer(file: FileInfo, api: API) {
  const j = api.jscodeshift.withParser("tsx");

  const $j = j(file.source);

  return $j
    .find(j.ImportDeclaration, { source: { value: "chakra-react-select" } })
    .forEach((path) => {
      const selectImport = j(path).find(j.ImportSpecifier);

      if (selectImport.size() === 0) {
        return;
      }

      // Find the names each of the four base Select components was imported as
      const variableNames: string[] = [];

      [
        "Select",
        "AsyncSelect",
        "CreatableSelect",
        "AsyncCreatableSelect",
      ].forEach((selectName) => {
        const variableIdentifier = j(path)
          .find(j.ImportSpecifier)
          .filter((importPath) => importPath.node.imported.name === selectName)
          .find(j.Identifier);

        if (variableIdentifier.size() === 0) {
          return;
        }

        const variableName = variableIdentifier.get("name").value;

        if (variableName) {
          variableNames.push(variableName);
        }
      });

      if (!variableNames.length) {
        return;
      }

      variableNames.forEach((variableName) => {
        const selectElements = $j.findJSXElements(variableName);

        selectElements.forEach((selectPath) => {
          const $select = j(selectPath);

          if ($select.size() === 0) {
            return;
          }

          // Remove `useBasicStyles` prop from all Select components
          $select
            .find(j.JSXAttribute)
            .filter((nodePath) => nodePath.node.name.name === "useBasicStyles")
            .remove();
        });
      });
    })
    .toSource();
}

And here's an example of the result of running the codemod:

image

I also tried replacing one of the attributes names, which doesn't appear to have this problem, so I'm not sure why the remove isn't working right:

          $select
            .find(j.JSXAttribute)
            .filter(
              (nodePath) => nodePath.node.name.name === "selectedOptionColor"
            )
            .forEach((attribute) =>
              j(attribute).replaceWith(
                j.jsxAttribute(
                  j.jsxIdentifier("selectedOptionColorScheme"),
                  attribute.node.value
                )
              )
            );

I tried Googling this issue, and looking through the previous issues on this repo, but don't think I've found anything relevant. If this is a duplicate however, feel free to close this issue.

@Daniel15
Copy link
Member

Daniel15 commented Oct 20, 2023

Interesting... I've never seen that XHP generics syntax before. Flow doesn't support it. so it's likely that most Meta employees probably don't even know this can be done in TypeScript (if they mainly use Flow and just use TypeScript for a few projects)

Are you using the TypeScript parser? Try your repro on https://astexplorer.net/ and ensure you click TypeScript in the dropdown list. If it repros on ASTExplorer, it would be good to get a link to your repo (just click the save button in the toolbar, and copy the URL)

@ElonVolo
Copy link
Collaborator

ElonVolo commented Oct 20, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants