jscodeshift icon indicating copy to clipboard operation
jscodeshift copied to clipboard

Support for type casting/predicates on Typescript transform files?

Open kitsune7 opened this issue 4 years ago • 6 comments

jscodeshift version: 0.13.0 node version: 16.13.0

command:

npx jscodeshift -t src/transforms/sort-imports --extensions=ts,tsx --parser=tsx "${TRANSFORM_FILE}.ts" --print --dry

I'm using Typescript in a project running jscodeshift and I get the following error when I try to run one of my transform files:

  22 | export const hasSpecifiers = (
  23 |   importNode: ImportDeclaration | null
> 24 | ): importNode is ImportWithSpecifiers => {
     |  ^
  25 |   return !!importNode?.specifiers?.length;
  26 | };
  27 |
    at Object._raise (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:147:45)
    at Object.raiseWithData (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:142:17)
    at Object.raise (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/error.js:91:17)
    at Object.semicolon (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/util.js:127:10)
    at Object.parseVarStatement (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:808:10)
    at Object.parseStatementContent (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:307:21)
    at Object.parseStatement (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:247:17)
    at Object.parseStatement (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/plugins/flow/index.js:1831:26)
    at Object.parseExportDeclaration (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/parser/statement.js:1965:17)
    at Object.parseExportDeclaration (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/src/plugins/flow/index.js:2150:22) {
  loc: Position { line: 24, column: 1 },
  pos: 580,
  code: 'BABEL_PARSE_ERROR',
  reasonCode: 'MissingSemicolon'
}

I've gotten a similar errors in the same project while trying to use type casting:

  27 |       if (!aIsImport && !bIsImport) return 0; // Don't sort body statements
  28 |
> 29 |       const sourceA = getImportSource(a as ImportDeclaration);
     |                                         ^
  30 |       const sourceB = getImportSource(b as ImportDeclaration);
  31 |
  32 |       const aIsThirdParty = isThirdPartySource(sourceA);
    at Object._raise (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:541:17)
    at Object.raiseWithData (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:534:17)
    at Object.raise (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:495:17)
    at Object.unexpected (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:3580:16)
    at Object.expect (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:3554:28)
    at Object.parseCallExpressionArguments (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11775:14)
    at Object.parseCoverCallAndAsyncArrowHead (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11698:29)
    at Object.parseSubscript (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11628:19)
    at Object.parseSubscript (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:6227:18)
    at Object.parseSubscripts (/Users/christopher.bradshawgetweave.com/Git/codemods/node_modules/.pnpm/@[email protected]/node_modules/@babel/parser/lib/index.js:11601:19) {
  loc: Position { line: 29, column: 40 },
  pos: 921,
  code: 'BABEL_PARSE_ERROR',
  reasonCode: 'UnexpectedToken'
}

Is there a way to support these features of Typescript being used on the transform files or is there a way to override the parser for the transform script itself and not just the transform target? The tsx parser on the target files works great and tests will actually run the same transforms without any problems, but it's an issue if I try to use the codemod for anything other than a test.

kitsune7 avatar Dec 10 '21 22:12 kitsune7

I'm also experiencing the same issue.

pcattori avatar Mar 23 '22 22:03 pcattori

Ran into this issue today as well while trying to create an object lookup based on the value returned from a JSXAttribute. Would be happy to help create some tests cases or even tackle this if someone can point me in the right direction.

jimmynotjim avatar Jul 27 '22 00:07 jimmynotjim

Would you be able to up to github a temporary repository that reproduces the error?

ElonVolo avatar Jul 27 '22 03:07 ElonVolo

Of course. Give me a day or two to wrap some things up and I'll get back to you with a link.

jimmynotjim avatar Jul 27 '22 03:07 jimmynotjim

Sorry for the delay, I'm a bit stumped. I created an example project but I can't reproduce the error. As far as I can tell the example is configured exactly the same as my current project that I encountered the issue, but at this point I have to assume it's a configuration problem on my end and not an issue with jscodeshift. If anyone else wants to dig into it, here's my example repo.

https://github.com/jimmynotjim/JSCodeshift-type-casting-error

This is exactly where the issue exists in my current project but runs just fine in the example: https://github.com/jimmynotjim/JSCodeshift-type-casting-error/blob/main/codemods/tsCastCodemodExample.ts#L52

jimmynotjim avatar Aug 01 '22 17:08 jimmynotjim

I was able to figure out the issue. In my haste to limit the reproduction repo I didn't match my current repo file organization 1:1. In my current repo, I co-locate the transform, tests, and fixtures in a directory with the transform name, and export the transformer via an index file. When running the transform, I've been utilizing node's behavior of mapping the directory name to the index file.

It looks something like this

codemodName/
    index.ts
    codemodName.ts
    codemodName.test.ts
    codemodName.testFixtures.ts

I've updated my reproduction repo to match my current repo's file organization. So now:

this throws an error: jscodeshift --parser tsx --extensions tsx -t ./codemods/tsCastCodemodExample ./src/components

but this works: jscodeshift --parser tsx --extensions tsx -t ./codemods/tsCastCodemodExample/tsCastCodemodExample.ts ./src/components

I'm unfortunately not experienced enough to understand the difference here. Is there a way to keep the shorter path to the directory or is the full file path a requirement in this situation?

jimmynotjim avatar Aug 01 '22 18:08 jimmynotjim