facebook / jscodeshift

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

bug?: Using ts parser does not replace correctly #511

Open rxliuli opened 2 years ago

rxliuli commented 2 years ago

I'm using Jscodeshift to replace the following code in astexplorer testing, but I get different results using babel/ts

export const systemCoreApi = wrapApiClient<ISystemApi>({  namespace: 'system' })

use babel parser

export const parser = "babel";

// Press ctrl+space for code completion
export default function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  root
    // .find(j.TSTypeReference)
    .find(j.Identifier, { name: "ISystemApi" })
    .replaceWith((path) => {
      path.node.name = "ISystemCoreApi";
      return path.node;
    });

  return root.toSource();
}

output

export const systemCoreApi = wrapApiClient<ISystemCoreApi>({  namespace: 'system' })

use ts parser

// jscodeshift can take a parser, like "babel", "babylon", "flow", "ts", or "tsx"
// Read more: https://github.com/facebook/jscodeshift#parser
export const parser = "ts";

// Press ctrl+space for code completion
export default function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  root
    // .find(j.TSTypeReference)
    .find(j.Identifier, { name: "ISystemApi" })
    .replaceWith((path) => {
      path.node.name = "ISystemCoreApi";
      return path.node;
    });

  return root.toSource();
}

output

export const systemCoreApi = wrapApiClient<ISystemApi>({  namespace: 'system' })

Lastly, I'm wondering how to use the @typescript-eslint/parser parser, it seems to work best for parsing ts in ast explorer (the result of ts parsing is very different from other parsers and jscodeshift's api)

image image

Daniel15 commented 2 years ago

Hmm, if I remove the export const parser = 'ts' and select TypeScript from the dropdown list on ASTExplorer, it works fine? https://astexplorer.net/#/gist/a87887cd564a07395d7f2b1a3f336d2a/2d968bb30b8ca3fdda9b8a31645f1d7e69ca8248

Lastly, I'm wondering how to use the @typescript-eslint/parser parser

Did you try

export const parser = "@typescript-eslint/parser";

otherwise you could look at the ASTExplorer source code and see how it does it :)

ElonVolo commented 2 years ago

I’ve looked into this a bit. If you go parser/tsOptions and remove line 42, ‘typescript’ it works.

There’s an entry in the docs for babel-plugin-transform-typescript that mentions:

“2. This plugin dos not support export = and import =“

I suspect this has something to do with it.

Sent from my iPhone

On Jul 25, 2022, at 19:58, Daniel Lo Nigro @.***> wrote:

 Hmm, if I remove the export const parser = 'ts' and select TypeScript from the dropdown list on ASTExplorer, it works fine? https://astexplorer.net/#/gist/a87887cd564a07395d7f2b1a3f336d2a/2d968bb30b8ca3fdda9b8a31645f1d7e69ca8248

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.

rxliuli commented 2 years ago

Hmm, if I remove the export const parser = 'ts' and select TypeScript from the dropdown list on ASTExplorer, it works fine?

Yes, but this doesn't actually use the ts parser, e.g. if you include an enum in it, it will error out

export const systemCoreApi = wrapApiClient<ISystemApi>({  namespace: 'system' })

export enum S {
 name = 1 
}

image

rxliuli commented 2 years ago

export const parser = "@typescript-eslint/parser";

Using it will give an error as if it's not used correctly, and I've also confirmed that the underlying recast is fine and can be used normally @typescript-eslint/parser

image