facebook / jscodeshift

A JavaScript codemod toolkit.
https://jscodeshift.com
MIT License
9.11k stars 468 forks source link

Generics are being removed from JSX Elements #572

Closed csandman closed 1 day ago

csandman commented 9 months ago

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 commented 9 months ago

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 commented 9 months ago

“most Meta employees don't even know this can be done in TypeScript.“

Then probably neither does recast. 😂

syi0808 commented 1 week ago

I can't repro on version 0.16.1.

csandman commented 1 day ago

Yeah for some reason this doesn't seem to be happening for me anymore, I'm not sure what exactly changed, but I'll close this out unless someone else runs into the same issue.

Daniel15 commented 1 day ago

Which parser are you using? Flow added support for this syntax a few months ago... Is it possible you're using the Flow parser?

On July 18, 2024 5:17:07 PM PDT, Chris Sandvik @.***> wrote:

Yeah for some reason this doesn't seem to be happening for me anymore, I'm not sure what exactly changed, but I'll close this out unless someone else runs into the same issue.

-- Reply to this email directly or view it on GitHub: https://github.com/facebook/jscodeshift/issues/572#issuecomment-2237802158 You are receiving this because you commented.

Message ID: @.***>