Giter Club home page Giter Club logo

ts-migrate's Introduction

ts-migrate

ts-migrate is a tool for helping migrate code to TypeScript. It takes a JavaScript, or a partial TypeScript, project in and gives a compiling TypeScript project out.

ts-migrate is intended to accelerate the TypeScript migration process. The resulting code will pass the build, but a followup is required to improve type safety. There will be lots of // @ts-expect-error, and any that will need to be fixed over time. In general, it is a lot nicer than starting from scratch.

ts-migrate is designed as a set of plugins so that it can be pretty customizable for different use-cases. Potentially, more plugins can be added for addressing things like improvements of type quality or libraries-related things (like prop-types in React).

Plugins are combined into migration configs. We currently have two main migration configs:

  • for the main JavaScript → TypeScript migration
  • for the reignore script

These configs can be moved out of the default script, and people can add custom configs with a different set of plugins for their needs.

You can find instructions on how to install and run ts-migrate in the main package. If you find any issues or have ideas for improvements, we welcome your contributions!

Check out the blog post about ts-migrate!

Published Packages

Folder Version Package
packages/ts-migrate npm version ts-migrate
packages/ts-migrate-plugins npm version ts-migrate-plugins
packages/ts-migrate-server npm version ts-migrate-server

Unpublished Packages

Folder Description
packages/ts-migrate-example basic example of usage of the ts-migrate-server with a writing a custom simple plugin

Authors


Brie Bunge

Sergii Rudenko

John Haytko

Elliot Sachs

Joe Lencioni

License

MIT, see LICENSE for details.

ts-migrate's People

Contributors

aloha-zzz avatar bmuenzenmeyer avatar caleb15 avatar calidus avatar catc avatar coderaiser avatar dependabot[bot] avatar edsrzf avatar egorio avatar ethanj-auditboard avatar gus3inov avatar isaacwashere avatar jamessingleton avatar jdmathew avatar joshchoo avatar justman00 avatar kentcdodds avatar kvz avatar lencioni avatar pytal avatar rudeg avatar runjuu avatar sawyerh avatar sfrieson avatar skovy avatar wdoug avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ts-migrate's Issues

Debug mode to prevent silent failures?

When I run ts-migrate on some of my folders, the process just quits without reporting either completion or failure, and no files have been modified.
I'm guessing there's a parsing error happening for some of my files, but I don't have any error output to help troubleshoot.

I'd like to be able to pass a --debug flag (or equivalent) to output such errors to the console.

Reached Javascript's memory limit

I was trying to convert a project I'm working on here https://github.com/aelgasser/ketcher.

After running ts-migrate init and ts-migrate rename I ran the migrate command, which, you'll see by the timings below took a lot of time :-) and eventually crashed over an Out of memory exception.

I'm running the migratin on a Mac Book Pro with macOS Catalina and 32GB of memory (though most of it is used in other tasks). Here a view the actual memory consumption :

image

Here is the call the issue. You can reproduce it with the master branch of my repo above.

ketcher git:(migrate-typescript) ✗ ts-migrate migrate .
forkTSServer
Logs in /var/folders/vx/rv39hv855zl5lnwrd94f2gs80000gr/T/ts-migrate-log-ao3ewO
TypeScript version: 3.9.7
Initialized tsserver project in 166.072ms.
Start...
[strip-ts-ignore] Plugin 1 of 12. Start...
[strip-ts-ignore] Finished in 1212.617ms.
[hoist-class-statics] Plugin 2 of 12. Start...
[hoist-class-statics] Finished in 432.065ms.
[react-props] Plugin 3 of 12. Start...
[react-props] Finished in 39.899ms.
[react-class-state] Plugin 4 of 12. Start...
[react-class-state] Finished in 587.065ms.
[react-class-lifecycle-methods] Plugin 5 of 12. Start...
[react-class-lifecycle-methods] Finished in 87.543ms.
[react-default-props] Plugin 6 of 12. Start...
[react-default-props] Finished in 2.223ms.
[react-shape] Plugin 7 of 12. Start...
[react-shape] Finished in 1.812ms.
[declare-missing-class-properties] Plugin 8 of 12. Start...
[declare-missing-class-properties] Finished in 591643.556ms.
[explicit-any] Plugin 9 of 12. Start...
[explicit-any] Finished in 4281997.169ms.
[eslint-fix] Plugin 10 of 12. Start...

<--- Last few GCs --->

[59989:0x108008000]  5021636 ms: Scavenge 2033.5 (2047.8) -> 2032.2 (2046.5) MB, 10.5 / 0.0 ms  (average mu = 0.335, current mu = 0.350) allocation failure 
[59989:0x108008000]  5021653 ms: Scavenge 2033.5 (2047.8) -> 2033.5 (2047.8) MB, 11.0 / 0.0 ms  (average mu = 0.335, current mu = 0.350) allocation failure 
[59989:0x108008000]  5021675 ms: Scavenge 2034.8 (2049.1) -> 2034.9 (2049.1) MB, 11.0 / 0.0 ms  (average mu = 0.335, current mu = 0.350) allocation failure 


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x1009ce8d9]
    1: StubFrame [pc: 0x100979382]
Security context: 0x07a6220c08d1 <JSObject>
    2: clone [0x7a605226921] [/Users/abderraouf.elgasser/projects/open_source/ketcher/node_modules/babel-eslint/node_modules/babylon/lib/index.js:~849] [pc=0xb15e09d5d0](this=0x07a615285d99 <State map = 0x7a685504f39>,0x07a672e004b1 <undefined>)
    3: parseConditional [0x7a6cfea7ab1] [/Users/abderraouf.elgasser/projects/open_...

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
 1: 0x1011bdf85 node::Abort() (.cold.1) [/usr/local/bin/node]
 2: 0x10009d569 node::Abort() [/usr/local/bin/node]
 3: 0x10009d6cf node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
 4: 0x1001de957 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 5: 0x1001de8f7 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 6: 0x100364635 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
 7: 0x100365e8a v8::internal::Heap::RecomputeLimits(v8::internal::GarbageCollector) [/usr/local/bin/node]
 8: 0x10036290e v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
 9: 0x1003606c0 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
10: 0x10036c4ea v8::internal::Heap::AllocateRawWithLightRetry(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
11: 0x10036c571 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
12: 0x10033a78a v8::internal::Factory::NewFillerObject(int, bool, v8::internal::AllocationType, v8::internal::AllocationOrigin) [/usr/local/bin/node]
13: 0x100689858 v8::internal::Runtime_AllocateInYoungGeneration(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
14: 0x1009ce8d9 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/usr/local/bin/node]
15: 0x100979382 Builtins_CloneFastJSArray [/usr/local/bin/node]
[1]    59989 abort      ts-migrate migrate .
➜  ketcher git:(migrate-typescript) ✗ 

Can't run tests locally on linux

Just cloned and installed repository and want to run tests, but it fails. Could you please help me?

coderaiser@cloudcmd:~/ts-migrate$ yarn test
yarn run v1.21.1
$ lerna run test
lerna notice cli v3.22.1
lerna info Executing command in 3 packages: "yarn run test"
ts-migrate-server: $ jest --config jest-config.json
ts-migrate-server:   console.log
ts-migrate-server:     log.info: TypeScript version: 3.9.7
ts-migrate-server:       at Object.info (tests/test-utils.ts:89:13)
ts-migrate-server:   console.log
ts-migrate-server:     log.info: Initialized tsserver project in 459.423ms.
ts-migrate-server:       at Object.info (tests/test-utils.ts:89:13)
ts-migrate-server:   console.log
ts-migrate-server:     log.info: Start...
ts-migrate-server:       at Object.info (tests/test-utils.ts:89:13)
ts-migrate-server:   console.log
ts-migrate-server:     log.info: [test-plugin] Plugin 1 of 1. Start...
ts-migrate-server:       at Object.info (tests/test-utils.ts:89:13)
ts-migrate-server: FAIL tests/commands/migrate/migrate.test.ts (6.51 s)
ts-migrate-server:   migrate command
ts-migrate-server:     ✕ Migrates project (5082 ms)
ts-migrate-server:   ● migrate command › Migrates project
ts-migrate-server:     : Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 5000 ms timeout specified by jest.setTimeout.Error:
ts-migrate-server:       24 |   });
ts-migrate-server:       25 | 
ts-migrate-server:     > 26 |   it('Migrates project', async () => {
ts-migrate-server:          |   ^
ts-migrate-server:       27 |     const inputDir = path.resolve(__dirname, 'input');
ts-migrate-server:       28 |     const outputDir = path.resolve(__dirname, 'output');
ts-migrate-server:       29 |     const configDir = path.resolve(__dirname, 'config');
ts-migrate-server:       at new Spec (../../node_modules/jest-jasmine2/build/jasmine/Spec.js:116:22)
ts-migrate-server:       at Suite.<anonymous> (tests/commands/migrate/migrate.test.ts:26:3)
ts-migrate-server: Test Suites: 1 failed, 1 total
ts-migrate-server: Tests:       1 failed, 1 total
ts-migrate-server: Snapshots:   0 total
ts-migrate-server: Time:        6.595 s, estimated 7 s
ts-migrate-server: Ran all test suites.
ts-migrate-server: error Command failed with exit code 1.
ts-migrate-server: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
lerna ERR! yarn run test exited 1 in 'ts-migrate-server'
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Repeated Migrations result in duplicate `@ts-expect-error ts-migrate(2578)` errors

While tracking down issues I was having with the eslint-plugin (#21), I ended up running the ts-migrate-full script several times. This resulted in a handful of repetitive @ts-expect-error directives:

147    const newProps = _(assignments)
148    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
149    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
150    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
151    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
152-207     ...
208    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
209    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
210    // @ts-expect-error ts-migrate(2578) FIXME: Unused '@ts-expect-error' directive.
211    // @ts-expect-error ts-migrate(2339) FIXME: Property 'user' does not exist on type 'unknown'.
212    .map(a => ({ user: a.user, dataType: a.dataType, ref: a.ref }))

[explicit-any]: missing case for error 7008

Looks like // TS7008: "Member '{0}' implicitly has an 'any' type" is not covered in explicit-any plugin.
From my experiments looks like the code for 7006 handles the interface case correctly

Example:

interface State {
  id;
  name;
}

However it doesn't handle this case:

export const foo = ({ id}: {
  id?; // this is converted to id: $TSFixMe?;
})

Side note:
I tried to make a PR but for some reason I'm getting a ton of TS error like (Binding element 'getLanguageService' implicitly has an 'any' type.ts(7031) in explicit-any.ts or even Cannot find module 'ts-migrate-server' or its corresponding type declarations.ts(2307).
I ran yarn and yarn build.

Unexpected semicolon

Hi, this fails in explicit-any phase

version 0.1.10

simplified version of code. I think props are the problem

const InfoPanel = props => {
  const { foo } = props;

  return (
    <div>{foo? 'bar' : 'bar2'}</bar>
  );
};

InfoPanel.propTypes = {
  foo: PropTypes.bool,
};

InfoPanel.defaultProps = {
  foo: false,
};

export default InfoPanel;

Stacktrace (from original code)

Error: [explicit-any][src\InfoPanel.tsx] Error:
 SyntaxError: Unexpected token, expected ";" (23:22)
    at Object.raise (C:\path\project\node_modules\@babel\parser\lib\index.js:6325:17)
    at Object.unexpected (C:\path\project\node_modules\@babel\parser\lib\index.js:7642:16)
    at Object.semicolon (C:\path\project\node_modules\@babel\parser\lib\index.js:7624:40)
    at Object.parseVarStatement (C:\path\project\node_modules\@babel\parser\lib\index.js:10300:10)
    at Object.parseStatementContent (C:\path\project\node_modules\@babel\parser\lib\index.js:9896:21)
    at Object.parseStatementContent (C:\path\project\node_modules\@babel\parser\lib\index.js:5372:18)
    at Object.parseStatement (C:\path\project\node_modules\@babel\parser\lib\index.js:9829:17)
    at Object.parseBlockOrModuleBlockBody (C:\path\project\node_modules\@babel\parser\lib\index.js:10405:25)
    at Object.parseBlockBody (C:\path\project\node_modules\@babel\parser\lib\index.js:10392:10)
    at Object.parseTopLevel (C:\path\project\node_modules\@babel\parser\lib\index.js:9758:10) {
  pos: 667,
  loc: Position { line: 23, column: 22 }
}

Expose as a NodeJS API

Hey team! Wanted to propose some stuff I would be willing to contribute, and thus wanted to see what your perspective was on it:

Proposal

Expose ts-migrate as a NodeJS API, such that teams could do something like:

const MigrationCLI = require('ts-migrate')

(async () => {
 const runner = new MigrationCLI();

 const FOLDER = process.cwd();
 const options = {
	// Configuration options go here
 }

 await runner.init(FOLDER, options)
 await runner.migrate(FOLDER, options)
})()

The async nature of this is similar to how ESLint handles their file manipulation. I think would open up the door for having parallel or threaded processes down the road in this case.

Motivation

I could see the case that many teams have specific project structure that may require additional setup. Having a code-mod that performs their setup, but also can migrate from JS to TS in the same tool, would be massively beneficial, and allows teams to become more opinionated on their own migration tool.

Thanks for your work as a team! Happy to get in contact for how I can help with design or contribution on this front 😄

Code mod causes broken code, if there is a comment before line with `PropTypes.shape(`

Content of original js file is:

import PropTypes from 'prop-types';

// eslint-disable-next-line import/prefer-default-export
export const MyPropType = PropTypes.shape({
    value: PropTypes.any.isRequired,
    title: PropTypes.string.isRequired,
});

After running codemod we get:

import PropTypes from 'prop-types';

type MyPropType = {
    value: any;
    title: string;
};

// eslint-disable-next-line import/prefer-default-export const MyPropType: PropTypes.Requireable<MyPropType> = PropTypes.shape({
    value: PropTypes.any.isRequired,
    // @ts-expect-error ts-migrate(2304) FIXME: Cannot find name 'title'.
    title: PropTypes.string.isRequired,
});
export { MyPropType };

Use tsconfig that's not at the root dir

My package structure is:

tsconfig.json
packages/
  **/*.ts

I'd like to only transform the files under packages, but I want to use the tsconfig.json at the root. However, that doesn't appear to be an option. The tool looks for packages/tsconfig.json.

λ ts-migrate reignore ~/code/tvui/packages                                                                                                                                                                              
TypeScript version: 4.1.2
npm run ts-migrate -- reignore <folder>

Re-run ts-ignore on a project

Positionals:
  folder                                                                         [string] [required]

Options:
  -h, --help  Show help                                                                    [boolean]

FileNotFoundError: File not found: /Users/nheiner/code/tvui/packages/tsconfig.json
    at RealFileSystemHost.getFileNotFoundErrorIfNecessary (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:1113:50)
    at RealFileSystemHost.readFileSync (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:999:24)
    at TransactionalFileSystem.readFileSync (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:1590:32)
    at TsConfigResolver.getTsConfigFileJson (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2440:38)
    at TsConfigResolver.decorator (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2288:46)
    at TsConfigResolver.parseJsonConfigFileContent (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2436:59)
    at TsConfigResolver.decorator (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2288:46)
    at TsConfigResolver.getCompilerOptions (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2405:21)
    at TsConfigResolver.decorator (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/common/dist/ts-morph-common.js:2288:46)
    at getTsConfigCompilerOptions (/Users/nheiner/code/ts-migrate/node_modules/@ts-morph/bootstrap/dist/ts-morph-bootstrap.js:215:37) {
  path: '/Users/nheiner/code/tvui/packages/tsconfig.json',
  code: 'ENOENT'
}

I think a more robust algorithm would be to do a find-up from the passed <folder>.

Problem migrating React 17 app

Guys, I'm having a problem when trying to migrate a react 17 app from js to typescript using ts-migrate.

I have setup a simple repository where the problem is possible to be reproduced: https://github.com/studiojms/react-ts-migration

Here are steps I did when trying to migrate this repo (with only a few components):

  1. First of all, I installed the types dependencies: yarn add -D @types/react @types/react-dom typescript
  2. Then I installed ts-migrate: yarn add -D ts-migrate
  3. And I started the process: npx ts-migrate-full src
  4. When the process started, I just answered yes to the questions, to proceed with the default configurations

And then, I got the following problem:

My react components, which don't have import React from 'react' anymore, didn't get converted...

Here is an example of my Button component after migration:

const Button = ({
  onClick,
  children
}: any) => {
  return (
    // @ts-expect-error ts-migrate(2304) FIXME: Cannot find name 'button'.
    <button type="button" onClick={onClick}>
      {children}
    </button>
  );
};

export default Button;

It seems like JSX is not recognized. My react components were renamed from js to ts (and not tsx).

Is there anything I could do to make ts-migrate recognize my react components, and migrate them from js to tsx?

I have setup this sample project to test, because I'm trying to migrate a large project (with more than 1000 files), but it turns out it is not recognizing my components... so, this sample project was to verify if it was conflicting with some other stuff in the project

How to migrate require -> import and module.exports -> export default

Hello
I have tried to use this package, but I have problem with auto migrate require to import and exports to export default.
Now when I ran npx ts-migrate-full it leaves me many lines:

// @ts-expect-error ts-migrate(2451) FIXME: Cannot redeclare block-scoped variable 'validation... Remove this comment to see the full error message
const validation = require('express-validation');

IMHO it should be migrated to import lines.
Maybe I'm missing something? Or I should migrate it manually first?

Regards
Tomasz

Unusabel npx ts-migrate -- reignore

% npx ts-migrate -- reignore      
Usage: npm run ts-migrate -- <command> [options]

Commands:
  npm run ts-migrate -- init <folder>               Initialize tsconfig.json file in <folder>
  npm run ts-migrate -- init:extended <folder>      Initialize tsconfig.json file in <folder>
  npm run ts-migrate -- rename [options] <folder>   Rename files in folder from JS/JSX to TS/TSX
  npm run ts-migrate -- migrate [options] <folder>  Fix TypeScript errors, using codemods
  npm run ts-migrate -- reignore <folder>           Re-run ts-ignore on a project

Options:
  -h, --help  Show help                                                                    [boolean]

Examples:
  npm run ts-migrate -- --help                        Show help
  npm run ts-migrate -- migrate --help                Show help for the migrate command
  npm run ts-migrate -- init frontend/foo             Create tsconfig.json file at
                                                      frontend/foo/tsconfig.json
  npm run ts-migrate -- init:extended frontend/foo    Create extended from the base tsconfig.json
                                                      file at frontend/foo/tsconfig.json
  npm run ts-migrate -- rename frontend/foo           Rename files in frontend/foo from JS/JSX to
                                                      TS/TSX
  npm run ts-migrate -- rename frontend/foo --s       Rename files in frontend/foo/bar/baz from
  "bar/baz"                                           JS/JSX to TS/TSX

Must provide a command.

On "ts-migrate": "^0.1.12",

how to remove all Unused '@ts-expect-error' directive

after run npx ts-migrate-full , I receive many errors about alias. after i resolve it.these annotation
// @ts-expect-error ts-migrate(2307) FIXME: Cannot find module '@/constants/types' or its corr... Remove this comment to see the full error message
now, i want remove all annotations like it .

Not picking up files to migrate

Hi there, I think this is an operator error situation but I'm going to explain what I'm trying to do and hopefully someone can call out where I'm going wrong.

Currently have a very large codebase and I'm trying to migrate each folder in the codebase one at a time to sanely manage the migration.

So I have a folder called lib/src/constants/ that contains the following files:

lib/src/constants
├── __mocks__
│   └── helpers.ts
├── apps.ts
├── helpers.ts
└── types.ts

Commands I'm running:

Step 1

yarn run ts-migrate init:extended lib/src/constants

This generates a boilerplate tsconfig.json within lib/src/constants. 👍🏽

Step 2
Replace tsconfig.json contents to point to the tsconfig.json that lives at the root of all the folders.

{
  "extends": "../../../tsconfig.json",
  "include": ["."]
}

Step 3

yarn run ts-migrate migrate lib/src/constants

Run the command above and get the output below.

TypeScript version: 4.1.2
Initialized tsserver project in 1649.462ms.
Start...
[strip-ts-ignore] Plugin 1 of 14. Start...
[strip-ts-ignore] Finished in 19.194ms.
[hoist-class-statics] Plugin 2 of 14. Start...
[hoist-class-statics] Finished in 1.508ms.
[react-props] Plugin 3 of 14. Start...
[react-props] Finished in 0.287ms.
[react-class-state] Plugin 4 of 14. Start...
[react-class-state] Finished in 0.265ms.
[react-class-lifecycle-methods] Plugin 5 of 14. Start...
[react-class-lifecycle-methods] Finished in 0.216ms.
[react-default-props] Plugin 6 of 14. Start...
[react-default-props] Finished in 0.618ms.
[react-shape] Plugin 7 of 14. Start...
[react-shape] Finished in 0.490ms.
[declare-missing-class-properties] Plugin 8 of 14. Start...
[declare-missing-class-properties] Finished in 647.272ms.
[member-accessibility] Plugin 9 of 14. Start...
[member-accessibility] Finished in 1.314ms.
[explicit-any] Plugin 10 of 14. Start...
[explicit-any] Finished in 28.786ms.
[add-conversions] Plugin 11 of 14. Start...
[add-conversions] Finished in 2.923ms.
[eslint-fix] Plugin 12 of 14. Start...
[eslint-fix] Finished in 2680.290ms.
[ts-ignore] Plugin 13 of 14. Start...
[ts-ignore] Finished in 0.755ms.
[eslint-fix] Plugin 14 of 14. Start...
[eslint-fix] Finished in 105.843ms.
Finished in 3490.653ms, for 14 plugin(s).
Writing 0 updated file(s)...
Wrote 0 updated file(s) in 0.041ms.

Says it wrote 0 updated files. 😿

Then I opened up one of the files to see if it removed the // @ts-ignore that was at the top but nothing has changed.

I'm currently trying to understand what files it's picking up and how to tell it what files to include. I thought tsconfig.json was doing that but appears to not be the case.

Any help here would be greatly appreciated. Otherwise I'll keep digging in the source code trying to figure what I'm doing wrong.

Error: Failed to add @ts-expect-error within template expression.

Who has encountered this problem?

TypeScript version: 4.0.2
Initialized tsserver project in 21864.213ms.
Start...
[strip-ts-ignore] Plugin 1 of 13. Start...
[strip-ts-ignore] Finished in 9671.452ms.
[hoist-class-statics] Plugin 2 of 13. Start...
[hoist-class-statics] Finished in 3010.238ms.
[react-props] Plugin 3 of 13. Start...
[react-props] Finished in 8997.580ms.
[react-class-state] Plugin 4 of 13. Start...
[react-class-state] Finished in 1146.588ms.
[react-class-lifecycle-methods] Plugin 5 of 13. Start...
[react-class-lifecycle-methods] Finished in 1230.168ms.
[react-default-props] Plugin 6 of 13. Start...
[react-default-props] Finished in 125.415ms.
[react-shape] Plugin 7 of 13. Start...
[react-shape] Finished in 74.528ms.
[declare-missing-class-properties] Plugin 8 of 13. Start...
[declare-missing-class-properties] Finished in 1527402.648ms.
[member-accessibility] Plugin 9 of 13. Start...
[member-accessibility] Finished in 251.822ms.
[explicit-any] Plugin 10 of 13. Start...
[explicit-any] Finished in 2598251.268ms.
[eslint-fix] Plugin 11 of 13. Start...
[eslint-fix] Finished in 5068.773ms.
[ts-ignore] Plugin 12 of 13. Start...
Error: [ts-ignore][src/cards/XXX.tsx] Error:
 Error: Failed to add @ts-expect-error within template expression.
    at /node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:69:27
    at Array.forEach (<anonymous>)
    at getTextWithIgnores (/node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:24:17)
    at Object.run (/node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:15:16)
    at Object.migrate (/node_modules/ts-migrate-server/build/src/migrate/index.js:73:46)
    at async Object.handler (/node_modules/ts-migrate/build/cli.js:128:22)
Error: [ts-ignore][src/cards/+IndustryDetail/IndustryMarketMovement/components/HotChart.tsx] Error:
 Error: Failed to add @ts-expect-error within template expression.
    at /node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:69:27
    at Array.forEach (<anonymous>)
    at getTextWithIgnores (/node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:24:17)
    at Object.run (/node_modules/ts-migrate-plugins/build/src/plugins/ts-ignore.js:15:16)
    at Object.migrate (/node_modules/ts-migrate-server/build/src/migrate/index.js:73:46)
    at async Object.handler (/node_modules/ts-migrate/build/cli.js:128:22)

How can we use this ts-migrate?

Hello everyone, how can we use this ts-migrate? Could you please provide us a demo about how a javascript file to typescript file when use this ts-migrate

Doesn't seem to work with pnpm package manager

I got this after running pnpx ts-migrate-full packages/*:

usr/local/bin/../pnpm-global/4/node_modules/ts-migrate/bin/ts-migrate-full.sh: line 66: /usr/local/bin/../pnpm-global/4/node_modules/ts-migrate/bin/ts-migrate: No such file or directory

Plugin to add class accessibility modifiers

Our JavaScript code base has a convention of prefixing private class properties and methods with underscores (eg _privateProperty). It would be great to have a ts-migrate plugin that would apply the appropriate accessibility modifier (private, protected, or public) based on this convention or similar ones.

As a sketch of a design, it could be regex-based and have these options:

type Options = {
  // The default accessibility modifier to add if there is no regex match.
  // undefined means that there is no modifier applied when no regex matches,
  // and the class element defaults to public.
  defaultModifier?: 'private' | 'protected' | 'public'

  // If a class element matches this regex, it is marked as private.
  privateRegex?: string;

  // If a class element matches this regex, it is marked as protected.
  protectedRegex?: string;

  // If a class element matches this regex, it is marked as public.
  publicRegex?: string;
};

If multiple regexes match, the priority is private > protected > public. The default options mean that no transformations are made.

The options I would use for the code base I'm working with would be:

{
  "defaultModifier": "public",
  "privateRegex": "^_"
}

This means that any class elements whose names match the regex /^_/ would be marked private and all other elements would be marked public. (We do not have a convention for protected names, and have very few in practice.)

Is this something that would be useful? Could it even be a default plugin, considering that the default options do nothing? Are there any thoughts on the design above?

SyntaxError on `import type`

When running the ts-migrate-full or ts-migrate migrate command, if there are any included files (imported as a dependency of the sources somewhere) that use the TypeScript 3.8+ syntax import type, the script fails with a SyntaxError: Unexpected token referencing that syntax.

How to enable $TSFixMe aliases?

What's the easiest way to enable the aliases for any etc, since they are disabled by default? Also, is there a way to provide custom aliases?

Errors parsing TypeScript config

(fifteen5) caleb•~/Documents/fifteen5(dev⚡)» yarn ts-migrate -- migrate ff/static/modules                                   [18:50:11]
yarn run v1.22.5
warning From Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts.
$ /home/caleb/Documents/fifteen5/node_modules/.bin/ts-migrate migrate ff/static/modules
forkTSServer
Logs in /tmp/ts-migrate-log-NvUlBG
npm run ts-migrate -- migrate <folder>

Fix TypeScript errors, using codemods

Positionals:
  folder                                                     [string] [required]

Options:
  -h, --help  Show help                                                [boolean]

Error: Errors parsing TypeScript config: error TS18003: No inputs were found in config file 'tsconfig.json'. Specified 'include' paths were '["ff/static/modules/**/*"]' and 'exclude' paths were '[]'.

    at Object.parseTSConfig (/home/caleb/Documents/fifteen5/node_modules/ts-migrate-server/build/src/migrate/ParseTSConfig.js:27:15)
    at Object.migrate (/home/caleb/Documents/fifteen5/node_modules/ts-migrate-server/build/src/migrate/index.js:15:41)
    at Object.handler (/home/caleb/Documents/fifteen5/node_modules/ts-migrate/build/cli.js:93:48)
    at Object.runCommand (/home/caleb/Documents/fifteen5/node_modules/yargs/build/lib/command.js:196:48)
    at Object.parseArgs [as _parseArgs] (/home/caleb/Documents/fifteen5/node_modules/yargs/build/lib/yargs.js:1043:55)
    at Object.get [as argv] (/home/caleb/Documents/fifteen5/node_modules/yargs/build/lib/yargs.js:986:25)
    at Object.<anonymous> (/home/caleb/Documents/fifteen5/node_modules/ts-migrate/build/cli.js:146:29)
    at Module._compile (internal/modules/cjs/loader.js:1138:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
    at Module.load (internal/modules/cjs/loader.js:986:32)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Typescript config:

{
    "compilerOptions": {
      "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
      "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
      "allowJs": true,                       /* Allow javascript files to be compiled. */
      "jsx": "react",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
      "noEmit": true,                        /* Do not emit outputs. */
      "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
      "strict": true,                           /* Enable all strict type-checking options. */
      "baseUrl": "./ff/static/modules",         /* Base directory to resolve non-absolute module names. */
      "esModuleInterop": true,                   /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
      "forceConsistentCasingInFileNames": true  /* Casing matters in linux OS! */
    },
    "include": [
      "ff/static/modules/**/*"
    ]
  }

Rough tree of relevant directories:

package.json
├── ff
│   ├── other folders
│   ├── static
│   │   ├── other folders
│   │   ├── modules
│   │   │   ├── module subfolders w/ partially migrated typescript files. This is what I want to run ts-migrate against

I tried adding a rootdir of ./ and ./ff/static/modules in my tsconfig but neither worked.

Note that I'm able to run yarn tsc without a TS18003 error

Doesn't seem to work with monorepos

I am trying to convert https://github.com/vega/vega/tree/master/packages/vega-util, which is a package in a monorepo and already has typings. Running npx ts-migrate-full packages/vega-util from the root results in the following logs and no changes to the files. Am I using the tool incorrectly or is it not intended for my use case?

Welcome to TS Migrate! :D

This script will migrate a frontend folder to a compiling (or almost compiling) TS project.

It is recommended that you take the following steps before continuing...

1. Make sure you have a clean git slate.
   Run `git status` to make sure you have no local changes that may get lost.
   Check in or stash your changes, then re-run this script.

2. Check out a new branch for the migration.
   For example, `git checkout -b dominik--ts-migrate` if you're migrating several folders or
   `git checkout -b dominik--ts-migrate-vega-util` if you're just migrating packages/vega-util.

3. Make sure you're on the latest, clean master.
   `git fetch origin master && git reset --hard origin/master`

4. Make sure you have the latest npm modules installed.
   `npm install` or `yarn install`

If you need help or have feedback, please file an issue on Github!

Continue? (y/N) y
Set a custom path for the typescript compiler. (It's an optional step. Skip if you don't need it. Default path is ./node_modules/.bin/tsc.):
Your default tsc path is ./node_modules/.bin/tsc.

[Step 1 of 4] Initializing ts-config for the "packages/vega-util"...

[dom/ts 39342f6e] [ts-migrate][vega-util] Init tsconfig.json file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 packages/vega-util/.eslintrc
/Users/dominik/Code/vega

[Step 2 of 4] Renaming files from JS/JSX to TS/TSX and updating project.json\...

No JS/JSX files to rename.
/Users/dominik/Code/vega

[Step 3 of 4] Fixing TypeScript errors...

forkTSServer
Logs in /var/folders/_s/gz7fn52j6g5_nfm3rq23jv1w0000gn/T/ts-migrate-log-y6wsPC
TypeScript version: 3.9.7
Initialized tsserver project in 189.054ms.
Start...
[strip-ts-ignore] Plugin 1 of 12. Start...
[strip-ts-ignore] Finished in 0.058ms.
[hoist-class-statics] Plugin 2 of 12. Start...
[hoist-class-statics] Finished in 0.046ms.
[react-props] Plugin 3 of 12. Start...
[react-props] Finished in 0.022ms.
[react-class-state] Plugin 4 of 12. Start...
[react-class-state] Finished in 0.027ms.
[react-class-lifecycle-methods] Plugin 5 of 12. Start...
[react-class-lifecycle-methods] Finished in 0.031ms.
[react-default-props] Plugin 6 of 12. Start...
[react-default-props] Finished in 0.029ms.
[react-shape] Plugin 7 of 12. Start...
[react-shape] Finished in 0.044ms.
[declare-missing-class-properties] Plugin 8 of 12. Start...
[declare-missing-class-properties] Finished in 0.016ms.
[explicit-any] Plugin 9 of 12. Start...
[explicit-any] Finished in 0.020ms.
[eslint-fix] Plugin 10 of 12. Start...
[eslint-fix] Finished in 0.020ms.
[ts-ignore] Plugin 11 of 12. Start...
[ts-ignore] Finished in 0.016ms.
[eslint-fix] Plugin 12 of 12. Start...
[eslint-fix] Finished in 0.014ms.
Finished in 0.880ms, for 12 plugin(s).
Writing 0 updated file(s)...
Wrote 0 updated file(s) in 0.019ms.
[dom/ts 0ddeacf8] [ts-migrate][vega-util] Run TS Migrate
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 packages/vega-util/.eslintrc
/Users/dominik/Code/vega

[Step 4 of 4] Checking for TS compilation errors (there shouldn't be any).

./node_modules/.bin/tsc -p packages/vega-util/tsconfig.json

---
All done!

The recommended next steps are...

1. Sanity check your changes locally by inspecting the commits and loading the affected pages.

2. Push your changes with `git push`.

3. Open a PR!

Add types when JSDoc

It would be really great if a fully-documented code with JSDoc could auto-resolve the types, as they are here, they are present, I think that it could be not that hard.

Recognize Existing .eslintrc.* file

It would be nice to be able to recognize if the folder already has a .eslintrc.* file. When I ran this in a folder that had a .eslintrc.json file, it created an empty .eslintrc file instead of adding to the .eslintrc.json.

npx ts-migrate-full FOLDER_PATH not working

Hello guys,

I've been trying to run the command to execute the scripts but unfortunately the VSCode terminal is not being able to find the specified path, I've tried on many different ways but there is something I'm probably missing out. Can you guys give me some pointers here?

Regards

Migrating from Flow to TS

This tool looks really promising. However, we are currently in the process of migrating our Flow codebase to TS.

Do you think that it would be possible to create some plugins to handle Flow to TS migrations? I'm currently using https://github.com/Khan/flow-to-ts but ts-migrate idea looks far more advanced 🙂

Always prompt [ Must provide a command ], no matter how I call the command

1.My environment:

Windows10
WebStorm2020.2.2
npm 6.13.4
node.js 12.16.1
ts-migrate 0.1.6

2.Error report & log


Administrator@TIONGEDESKTOP MINGW64 /d/Program_Files/JetBrains_ToolBox/projects/WebStorm/use-on-demand (master)
$ ts-migrate -- init aaa
Usage: npm run ts-migrate -- <command> [options]

Commands:
  npm run ts-migrate -- init <folder>       Initialize tsconfig.json file in
                                            <folder>
  npm run ts-migrate -- init:extended       Initialize tsconfig.json file in
  <folder>                                  <folder>
  npm run ts-migrate -- rename <folder>     Rename files in folder from JS/JSX
                                            to TS/TSX
  npm run ts-migrate -- migrate <folder>    Fix TypeScript errors, using
                                            codemods
  npm run ts-migrate -- reignore <folder>   Re-run ts-ignore on a project

Options:
  -h, --help  Show help                                                [boolean]

Examples:
  npm run ts-migrate -- --help              Show help
  npm run ts-migrate -- init frontend/foo   Create tsconfig.json file at
                                            frontend/foo/tsconfig.json
  npm run ts-migrate -- init:extended       Create extended from the base
  frontend/foo                              tsconfig.json file at
                                            frontend/foo/tsconfig.json
  npm run ts-migrate -- rename              Rename files in frontend/foo from
  frontend/foo                              JS/JSX to TS/TSX

Must provide a command.

3.Other Info

$ npm run ts-migrate -- migrate "./"
npm ERR! missing script: ts-migrate

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\Administrator\AppData\Roaming\npm-cache\_logs\2020-09-28T03_56_16_853Z-debug.log

I did not manually add the [ts-migrate] script, because the [Repo Document] did not say to do so.

4._

Type 'C' cannot be used to index type 'Commands'.

I am getting this compiler error.

node_modules/ts-migrate-server/build/src/tsserver/commands.d.ts:303:66 - error TS2536: Type 'C' cannot be used to index type 'Commands'.

303 export declare type CommandRequest<C extends tsp.CommandTypes> = Commands[C]['request'];

The system cannot find the path specified

Given a folder structure like

my-app
├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    ├── logo.svg
    └── serviceWorker.js
    └── setupTests.js

When I cd into my-app, npm i -D ts-migrate and run npx ts-migrate-full src I am told that the system cannot find the path specified.

System:

  • OS: Windows 10 10.0.19042
  • CPU: (16) x64 AMD Ryzen 7 2700X Eight-Core Processor
  • Memory: 7.43 GB / 15.95 GB

Binaries:

  • Node: 12.18.3 - C:\Program Files\nodejs\node.EXE
  • Yarn: 1.22.4 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
  • npm: 6.14.8 - D:\Coding\github_work\fetchye\node_modules.bin\npm.CMD

npmGlobalPackages:

  • npm: 6.14.6

reignore erroneously duplicates the last part of a file

I'm seeing one of my files get erroneously modified by the codemod.

$ ts-migrate reignore .
TypeScript version: 4.1.2
Initialized tsserver project in 14353.990ms.
Start...
[strip-ts-ignore] Plugin 1 of 3. Start...
[strip-ts-ignore] Finished in 2214.610ms.
[ts-ignore] Plugin 2 of 3. Start...
[ts-ignore] Finished in 507805.555ms.
[eslint-fix-changed] Plugin 3 of 3. Start...
[eslint-fix-changed] Finished in 14272.833ms.
Finished in 524295.523ms, for 3 plugin(s).
Writing 420 updated file(s)...
Wrote 420 updated file(s) in 87.555ms.

Problematic file, before it was modified:

/** 100 lines omitted from this GH issue */
export function gridList(itemArea: Area, itemsPerRowOrColumn: number) {
    return new GridBuilder(itemArea, itemsPerRowOrColumn);
}

export function variableItemList(minItemArea: Area) {
    return new MinItemBuilder(minItemArea);
}

After transformation:

/** 100 lines omitted from this GH issue */
export function gridList(itemArea: Area, itemsPerRowOrColumn: number) {
    return new GridBuilder(itemArea, itemsPerRowOrColumn);
}

export function variableItemList(minItemArea: Area) {
    return new MinItemBuilder(minItemArea);
}
er) {
    return new GridBuilder(itemArea, itemsPerRowOrColumn);
}

export function variableItemList(minItemArea: Area) {
    return new MinItemBuilder(minItemArea);
}

Starting from the er) { line, you can see the end of the file has been repeated.

I tried to create a minimal repro of this outside of my repo but was unable to.

I tried resetting the files and rerunning the command, and got the same result.

ts-migrate haven't supported yarn yet?

npx works well but generally I use yarn so I just want to know that.

What I got when ran yarn ts-migrate-full src

$ yarn ts-migrate-full src
yarn run v1.22.5
$ /Users/koji/Documents/github/React-Hooks-StarterFiles/react-hooks-videoplayer/node_modules/.bin/ts-migrate-full src
Welcome to TS Migrate! :D

This script will migrate a frontend folder to a compiling (or almost compiling) TS project.

It is recommended that you take the following steps before continuing...

1. Make sure you have a clean git slate.
   Run `git status` to make sure you have no local changes that may get lost.
   Check in or stash your changes, then re-run this script.

2. Check out a new branch for the migration.
   For example, `git checkout -b koji--ts-migrate` if you're migrating several folders or
   `git checkout -b koji--ts-migrate-src` if you're just migrating src.

3. Make sure you're on the latest, clean master.
   `git fetch origin master && git reset --hard origin/master`

4. Make sure you have the latest npm modules installed.
   `npm install` or `yarn install`

If you need help or have feedback, please file an issue on Github!

Continue? (y/N) y
Set a custom path for the typescript compiler. (It's an optional step. Skip if you don't need it. Default path is ./node_modules/.bin/tsc.):
Your default tsc path is ./node_modules/.bin/tsc.

[Step 1 of 4] Initializing ts-config for the "src"...

Config file created at /Users/koji/Documents/github/React-Hooks-StarterFiles/react-hooks-videoplayer/src/tsconfig.json
[test/ts-test d5b59ba] [ts-migrate][src] Init tsconfig.json file
 2 files changed, 69 insertions(+)
 create mode 100644 src/.eslintrc
 create mode 100644 src/tsconfig.json
/Users/koji/Documents/github/React-Hooks-StarterFiles/react-hooks-videoplayer

[Step 2 of 4] Renaming files from JS/JSX to TS/TSX and updating project.json\...

Renaming 21 JS/JSX files in /Users/koji/Documents/github/React-Hooks-StarterFiles/react-hooks-videoplayer/src...
Done.
[test/ts-test 86fe968] [ts-migrate][src] Rename files from JS/JSX to TS/TSX
 21 files changed, 0 insertions(+), 0 deletions(-)
 rename src/components/{Darkmode.js => Darkmode.tsx} (100%)
 rename src/components/{PlaylistHeader.js => PlaylistHeader.tsx} (100%)
 rename src/components/{PlaylistItem.js => PlaylistItem.tsx} (100%)
 rename src/components/{Video.js => Video.tsx} (100%)
 rename src/components/containers/{App.js => App.tsx} (100%)
 rename src/components/containers/{Playlist.js => Playlist.tsx} (100%)
 rename src/components/containers/{PlaylistItems.js => PlaylistItems.tsx} (100%)
 rename src/components/containers/{WbnPlayer.js => WbnPlayer.tsx} (100%)
 rename src/components/hoc/{withLink.js => withLink.tsx} (100%)
 rename src/components/styles/{GlobalStyle.js => GlobalStyle.ts} (100%)
 rename src/components/styles/{StyledDarkmode.js => StyledDarkmode.ts} (100%)
 rename src/components/styles/{StyledJourney.js => StyledJourney.ts} (100%)
 rename src/components/styles/{StyledPlaylist.js => StyledPlaylist.ts} (100%)
 rename src/components/styles/{StyledPlaylistHeader.js => StyledPlaylistHeader.ts} (100%)
 rename src/components/styles/{StyledPlaylistItem.js => StyledPlaylistItem.ts} (100%)
 rename src/components/styles/{StyledPlaylistitems.js => StyledPlaylistitems.ts} (100%)
 rename src/components/styles/{StyledVideo.js => StyledVideo.ts} (100%)
 rename src/components/styles/{StyledVideoWrapper.js => StyledVideoWrapper.ts} (100%)
 rename src/components/styles/{StyledWbnPlayer.js => StyledWbnPlayer.ts} (100%)
 rename src/{index.js => index.tsx} (100%)
 rename src/{serviceWorker.js => serviceWorker.ts} (100%)
/Users/koji/Documents/github/React-Hooks-StarterFiles/react-hooks-videoplayer

[Step 3 of 4] Fixing TypeScript errors...

forkTSServer
Logs in /var/folders/gj/x6v5vwdx1v7741fdfcxwmr100000gn/T/ts-migrate-log-Wcz6EP
TypeScript version: 3.9.7
Initialized tsserver project in 195.893ms.
Start...
[strip-ts-ignore] Plugin 1 of 12. Start...
[strip-ts-ignore] Finished in 52.156ms.
[hoist-class-statics] Plugin 2 of 12. Start...
[hoist-class-statics] Finished in 19.066ms.
[react-props] Plugin 3 of 12. Start...
[react-props] Finished in 16.119ms.
[react-class-state] Plugin 4 of 12. Start...
[react-class-state] Finished in 1.862ms.
[react-class-lifecycle-methods] Plugin 5 of 12. Start...
[react-class-lifecycle-methods] Finished in 8.864ms.
[react-default-props] Plugin 6 of 12. Start...
[react-default-props] Finished in 0.953ms.
[react-shape] Plugin 7 of 12. Start...
[react-shape] Finished in 1.236ms.
[declare-missing-class-properties] Plugin 8 of 12. Start...
[declare-missing-class-properties] Finished in 1370.166ms.
[explicit-any] Plugin 9 of 12. Start...
[explicit-any] Finished in 329.848ms.
[eslint-fix] Plugin 10 of 12. Start...
[eslint-fix] Finished in 918.725ms.
[ts-ignore] Plugin 11 of 12. Start...
[ts-ignore] Finished in 363.458ms.
[eslint-fix] Plugin 12 of 12. Start...
[eslint-fix] Finished in 196.472ms.
Finished in 3279.939ms, for 12 plugin(s).
Writing 21 updated file(s)...
Wrote 21 updated file(s) in 3.068ms.
rm: src/.eslintrc.*: No such file or directory
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

[Feature] Output Types from JSDoc comments

I think it would be really awesome to be able to use types that are defined in JSDoc comments to output types with this tool. Seems that it would be developed as a plugin for the base tool.

I'd be happy to try and start this work, but have to admit I have pretty cursory knowledge of Typescript and would not really know where to start.

Does not work inside workspaces

/bin/sh: /Users/psenders/Documents/code/design-system-web/packages/components/node_modules/.bin/tsc: No such file or directory
/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/node_modules/yargs/build/lib/yargs.js:1132
                throw err;
                ^

Error: Command failed: $(npm bin)/tsc --init
/bin/sh: /Users/psenders/Documents/code/design-system-web/packages/components/node_modules/.bin/tsc: No such file or directory

    at checkExecSyncError (child_process.js:630:11)
    at Object.execSync (child_process.js:666:15)
    at Object.init [as default] (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/build/commands/init.js:27:25)
    at Object.handler (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/build/cli.js:20:19)
    at Object.runCommand (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/node_modules/yargs/build/lib/command.js:196:48)
    at Object.parseArgs [as _parseArgs] (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/node_modules/yargs/build/lib/yargs.js:1043:55)
    at Object.get [as argv] (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/node_modules/yargs/build/lib/yargs.js:986:25)
    at Object.<anonymous> (/Users/psenders/Documents/code/design-system-web/node_modules/ts-migrate/build/cli.js:146:29)
    at Module._compile (internal/modules/cjs/loader.js:1137:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10) {
  status: 127,
  signal: null,
  output: [
    null,
    Buffer(0) [Uint8Array] [],
    Buffer(127) [Uint8Array] [
       47,  98, 105, 110,  47, 115, 104,  58,  32,  47,  85, 115,
      101, 114, 115,  47, 112, 115, 101, 110, 100, 101, 114, 115,
       47,  68, 111,  99, 117, 109, 101, 110, 116, 115,  47,  99,
      111, 100, 101,  47, 100, 101, 115, 105, 103, 110,  45, 115,
      121, 115, 116, 101, 109,  45, 119, 101,  98,  47, 112,  97,
       99, 107,  97, 103, 101, 115,  47,  99, 111, 109, 112, 111,
      110, 101, 110, 116, 115,  47, 110, 111, 100, 101,  95, 109,
      111, 100, 117, 108, 101, 115,  47,  46,  98, 105, 110,  47,
      116, 115,  99,  58,
      ... 27 more items
    ]
  ],
  pid: 20090,
  stdout: Buffer(0) [Uint8Array] [],
  stderr: Buffer(127) [Uint8Array] [
     47,  98, 105, 110,  47, 115, 104,  58,  32,  47,  85, 115,
    101, 114, 115,  47, 112, 115, 101, 110, 100, 101, 114, 115,
     47,  68, 111,  99, 117, 109, 101, 110, 116, 115,  47,  99,
    111, 100, 101,  47, 100, 101, 115, 105, 103, 110,  45, 115,
    121, 115, 116, 101, 109,  45, 119, 101,  98,  47, 112,  97,
     99, 107,  97, 103, 101, 115,  47,  99, 111, 109, 112, 111,
    110, 101, 110, 116, 115,  47, 110, 111, 100, 101,  95, 109,
    111, 100, 117, 108, 101, 115,  47,  46,  98, 105, 110,  47,
    116, 115,  99,  58,
    ... 27 more items
  ]
}
error Command failed with exit code 1.```

inline function implicit any support

I think it makes sense to not add any to inline functions and it's better to leave them for TS to manually infer. It makes migration a bit easier and safer. Example:

// utils.ts  =< TS file
function addOne(input: number): number {
  return input + 1;
}

// foo.js
function f(input) {
  input.map(x => addOne(x))
}

### after ts-migrate runs (foo.ts)

function f(input: any) {
  input.map((x: any) => addOne(x));   // <= I want to keep x implicit
}

// when I type `input` I don't get error on the inline
function g(input: string[]) {
  input.map((x: any) => addOne(x)); // no error
}

// What I want: adding types to f will infer correctly and detect an error
function f(input: string[]) {
  input.map(x => addOne(x)); // Argument of type 'string' is not assignable to parameter of type 'number'.(2345)
}

Does not seem to support React forwardRef

Hi,

This project is great! However, it doesn't seem to support well forwardRefs in React.
I'm not sure if this is an issue or a feature request, but here is an example with a simple input:

Without forwardRef

JS file
import React, { memo } from "react";
import PropTypes from "prop-types";

const propTypes = {
  label: PropTypes.string.isRequired,
  className: PropTypes.string,
  onChange: PropTypes.func,
};

const defaultProps = {
  className: "",
  onChange: undefined,
};

const TestInput = ({ label, className, onChange, ...props }) => {
  return (
    <div className={className}>
      <label>
        {label}
        <input onChange={onChange} {...props} />
      </label>
    </div>
  );
};

TestInput.propTypes = propTypes;
TestInput.defaultProps = defaultProps;

export default memo(TestInput);
TS file after migration
import React, { memo } from "react";

type OwnProps = {
  label: string;
  className?: string;
  onChange?: (...args: any[]) => any;
};

const defaultProps = {
  className: "",
  onChange: undefined,
};

type Props = OwnProps & typeof defaultProps;

const TestInput = ({ label, className, onChange, ...props }: Props) => {
  return (
    <div className={className}>
      <label>
        {label}
        <input onChange={onChange} {...props} />
      </label>
    </div>
  );
};
TestInput.defaultProps = defaultProps;

export default memo(TestInput);

With forwardRef

JS file
import React, { memo, forwardRef } from "react";
import PropTypes from "prop-types";

const propTypes = {
  label: PropTypes.string.isRequired,
  className: PropTypes.string,
  onChange: PropTypes.func,
};

const defaultProps = {
  className: "",
  onChange: undefined,
};

const TestInput = forwardRef(({ label, className, onChange, ...props }, ref) => {
  return (
    <div className={className}>
      <label>
        {label}
        <input ref={ref} onChange={onChange} {...props} />
      </label>
    </div>
  );
});

TestInput.propTypes = propTypes;
TestInput.defaultProps = defaultProps;

export default memo(TestInput);
Actual TS file after migration

PropTypes are not converted to types.

import React, { memo, forwardRef } from "react";
import PropTypes from "prop-types";

const propTypes = {
  label: PropTypes.string.isRequired,
  className: PropTypes.string,
  onChange: PropTypes.func,
};

const defaultProps = {
  className: "",
  onChange: undefined,
};

// @ts-expect-error ts-migrate(2339) FIXME: Property 'label' does not exist on type '{ childre... Remove this comment to see the full error message
const TestInput = forwardRef(({ label, className, onChange, ...props }, ref) => {
  return (
    <div className={className}>
      <label>
        {label}
        {/* @ts-expect-error ts-migrate(2322) FIXME: Type 'unknown' is not assignable to type 'HTMLInpu... Remove this comment to see the full error message */}
        <input ref={ref} onChange={onChange} {...props} />
      </label>
    </div>
  );
});

// @ts-expect-error ts-migrate(2559) FIXME: Type '{ label: Validator<string>; className: Requi... Remove this comment to see the full error message
TestInput.propTypes = propTypes;
// @ts-expect-error ts-migrate(2559) FIXME: Type '{ className: string; onChange: undefined; }'... Remove this comment to see the full error message
TestInput.defaultProps = defaultProps;

export default memo(TestInput);
Expected TS file after migration
import React, { memo, forwardRef } from "react";

type OwnProps = {
  label: string;
  className?: string;
  onChange?: (...args: any[]) => any;
};

const defaultProps = {
  className: "",
  onChange: undefined,
};

type Props = OwnProps & typeof defaultProps;

const TestInput = forwardRef<HTMLInputElement, Props>(({ label, className, onChange, ...props }, ref) => {
  return (
    <div className={className}>
      <label>
        {label}
        <input ref={ref} onChange={onChange} {...props} />
      </label>
    </div>
  );
});
TestInput.defaultProps = defaultProps;

export default memo(TestInput);

Regards

Support for running on subfolders

Right now, we have to copy/paste our tsconfig file into any subfolders we want to process as explained by this comment: #7 (comment)

I'm working on a proof of concept for our team right now using this tool by only converting a few folders instead of the entire project. While I can definitely work around it, it would be really nice to specify the location of an existing tsconfig file, and have it use that instead of creating one in the subfolder.

Custom plugins

I'm playing with ts-migrate on our code base and have developed some custom plugins which are useful for us, but probably not general enough to be worth including in ts-migrate itself. I would like to have a way to run these plugins without having to maintain a fork of ts-migrate.

Is this something that the project would consider supporting?

The prop value with an expression type of JSXFragment could not be resolved

F:\fifteen5>yarn ts-migrate -- migrate .
yarn run v1.17.3
warning From Yarn 1.0 onwards, scripts don't require "--" for options to be forwarded. In a future version, any explicit "--" will be forwarded as-is to the scripts.
$ F:\fifteen5\node_modules\.bin\ts-migrate migrate .
TypeScript version: 4.0.2
Initialized tsserver project in 11306.893ms.
Start...
[strip-ts-ignore] Plugin 1 of 13. Start...
[strip-ts-ignore] Finished in 1721.592ms.
[hoist-class-statics] Plugin 2 of 13. Start...
[hoist-class-statics] Finished in 131.569ms.
[react-props] Plugin 3 of 13. Start...
[react-props] Finished in 1325.490ms.
[react-class-state] Plugin 4 of 13. Start...
[react-class-state] Finished in 29.595ms.
[react-class-lifecycle-methods] Plugin 5 of 13. Start...
[react-class-lifecycle-methods] Finished in 24.858ms.
[react-default-props] Plugin 6 of 13. Start...
[react-default-props] Finished in 16.059ms.
[react-shape] Plugin 7 of 13. Start...
[react-shape] Finished in 29.035ms.
[declare-missing-class-properties] Plugin 8 of 13. Start...
[declare-missing-class-properties] Finished in 433972.549ms.
[member-accessibility] Plugin 9 of 13. Start...
[member-accessibility] Finished in 87.888ms.
[explicit-any] Plugin 10 of 13. Start...
[explicit-any] Finished in 430783.822ms.
[eslint-fix] Plugin 11 of 13. Start...
The prop value with an expression type of JSXFragment could not be resolved. Please file issue to get this fixed immediately.
The prop value with an expression type of JSXFragment could not be resolved. Please file issue to get this fixed immediately.
The prop value with an expression type of JSXFragment could not be resolved. Please file issue to get this fixed immediately.
[eslint-fix] Finished in 768580.781ms.
[ts-ignore] Plugin 12 of 13. Start...
[ts-ignore] Finished in 491808.940ms.
[eslint-fix] Plugin 13 of 13. Start...
The prop value with an expression type of JSXFragment could not be resolved. Please file issue to get this fixed immediately.
[eslint-fix] Finished in 367601.743ms.
Finished in 2496130.800ms, for 13 plugin(s).
Writing 1568 updated file(s)...
Wrote 1568 updated file(s) in 365.166ms.
Done in 2510.79s.

Node 14,15.1, windows 10, ts-migrate 0.1.10.

Code mod causes syntax errors on single arity functions without parenthesis

We have a large JavaScript project using an older version of Prettier that removes parenthesis from functions with one argument.

Example:

const MyComponent = props => {
    /* My mediocre code */
}

The code mod will then add types to these function signatures without first checking to see if they have parenthesis:

const MyComponent =props: MyComponentProps => {
    /* My mediocre code */
}

When this happens to a few hundred files, it's pretty cumbersome to manually fix. :)

We were able to work around it by changing our Prettier config to always include parenthesis, reformatting the code, and then the code mod. It then worked as intended. It would be awesome if the code mod could wrap single arity functions with parenthesis to avoid having to do this.

Thank you for this AMAZING library!

Argument name clash

Sometimes I get

version 0.1.10

[declare-missing-class-properties] Plugin 8 of 13. Start...
Error: [declare-missing-class-properties][build\mainCtrl.ts] Error:
 SyntaxError: Argument name clash (1:81)
    at Object.raise (C:\path\project\node_modules\@babel\parser\lib\index.js:6325:17)
    at Object.checkLVal (C:\path\project\node_modules\@babel\parser\lib\index.js:8010:18)
    at Object.checkLVal (C:\path\project\node_modules\@babel\parser\lib\index.js:5727:15)
    at Object.checkParams (C:\path\project\node_modules\@babel\parser\lib\index.js:9449:12)
    at Object.parseFunctionBody (C:\path\project\node_modules\@babel\parser\lib\index.js:9423:12)
    at Object.parseFunctionBodyAndFinish (C:\path\project\node_modules\@babel\parser\lib\index.js:9394:10)
    at Object.parseFunctionBodyAndFinish (C:\path\project\node_modules\@babel\parser\lib\index.js:5219:11)
    at C:\path\project\node_modules\@babel\parser\lib\index.js:10535:12
    at Object.withTopicForbiddingContext (C:\path\project\node_modules\@babel\parser\lib\index.js:9702:14)
    at Object.parseFunction (C:\path\project\node_modules\@babel\parser\lib\index.js:10534:10) {
  pos: 81,
  loc: Position { line: 1, column: 81 }
}
Error: [declare-missing-class-properties][build\parameters\parametrizationGroup.ts] Error:
 SyntaxError: Argument name clash (3:54)
    at Object.raise (C:\path\project\node_modules\@babel\parser\lib\index.js:6325:17)
    at Object.checkLVal (C:\path\project\node_modules\@babel\parser\lib\index.js:8010:18)
    at Object.checkLVal (C:\path\project\node_modules\@babel\parser\lib\index.js:5727:15)
    at Object.checkParams (C:\path\project\node_modules\@babel\parser\lib\index.js:9449:12)
    at Object.parseFunctionBody (C:\path\project\node_modules\@babel\parser\lib\index.js:9423:12)
    at Object.parseFunctionBodyAndFinish (C:\path\project\node_modules\@babel\parser\lib\index.js:9394:10)
    at Object.parseFunctionBodyAndFinish (C:\path\project\node_modules\@babel\parser\lib\index.js:5219:11)
    at C:\path\project\node_modules\@babel\parser\lib\index.js:10535:12
    at Object.withTopicForbiddingContext (C:\path\project\node_modules\@babel\parser\lib\index.js:9702:14)
    at Object.parseFunction (C:\path\project\node_modules\@babel\parser\lib\index.js:10534:10) {
  pos: 237,
  loc: Position { line: 3, column: 54 }
}

Hard to tell when this happens or what causes it. Maybe add better logging if it is possible.

Proptypes plugin fails when proptypes are destructured

The prop types plugin fails to properly convert proptypes to TS types when the proptypes import is destructured. See the below example:

import React from "react";
import { node, string } from "prop-types";

const Foo = ({ children, className }) => {
  return <div className={className}>children</div>;
};

Foo.propTypes = {
  children: node,
  className: string,
};

export default Foo;

Relevant code:
https://github.com/airbnb/ts-migrate/blob/master/packages/ts-migrate-plugins/src/plugins/utils/react-props.ts#L115

The check on this line fails and a type reference node is created instead. Not sure what the best solution would be but it would probably involve keeping track of the identifiers from the import of prop-types. Happy to hear any pointers and I could take a stab at writing a PR for it.

Subfolder ts-migrate-full fails

I'm trying to slowly migrate subfolders of https://github.com/apache/incubator-superset, but they seem to fail on the eslint-fix step because the folder cli argument isn't there. Logs are below:

(venv) erik-ritters-MacBook-Pro:superset-frontend erik_ritter$ npx ts-migrate-full src/CRUD
Welcome to TS Migrate! :D

This script will migrate a frontend folder to a compiling (or almost compiling) TS project.

It is recommended that you take the following steps before continuing...

1. Make sure you have a clean git slate.
   Run `git status` to make sure you have no local changes that may get lost.
   Check in or stash your changes, then re-run this script.

2. Check out a new branch for the migration.
   For example, `git checkout -b erik_ritter--ts-migrate` if you're migrating several folders or
   `git checkout -b erik_ritter--ts-migrate-CRUD` if you're just migrating src/CRUD.

3. Make sure you're on the latest, clean master.
   `git fetch origin master && git reset --hard origin/master`

4. Make sure you have the latest npm modules installed.
   `npm install` or `yarn install`

If you need help or have feedback, please file an issue on Github!

Continue? (y/N) y
Set a custom path for the typescript compiler. (It's an optional step. Skip if you don't need it. Default path is ./node_modules/.bin/tsc.): 
Your default tsc path is ./node_modules/.bin/tsc.

[Step 1 of 4] Initializing ts-config for the "src/CRUD"...

Config file created at /Users/erik_ritter/repos/github.com/incubator-superset/superset-frontend/src/CRUD/tsconfig.json
seed isort known_third_party.............................................Passed
isort................................................(no files to check)Skipped
mypy.................................................(no files to check)Skipped
pip-compile-multi verify.............................(no files to check)Skipped
Check for added large files..............................................Passed
Check docstring is first.............................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)............................(no files to check)Skipped
Fix End of Files.........................................................Passed
Trim Trailing Whitespace.................................................Passed
black................................................(no files to check)Skipped
[detached HEAD 83f4f6aa7] [ts-migrate][CRUD] Init tsconfig.json file
 2 files changed, 66 insertions(+)
 create mode 100644 superset-frontend/src/CRUD/.eslintrc
 create mode 100644 superset-frontend/src/CRUD/tsconfig.json
/Users/erik_ritter/repos/github.com/incubator-superset/superset-frontend

[Step 2 of 4] Renaming files from JS/JSX to TS/TSX and updating project.json\...

Renaming 3 JS/JSX files in /Users/erik_ritter/repos/github.com/incubator-superset/superset-frontend/src/CRUD...
Done.
seed isort known_third_party.............................................Passed
isort................................................(no files to check)Skipped
mypy.................................................(no files to check)Skipped
pip-compile-multi verify.............................(no files to check)Skipped
Check for added large files..............................................Passed
Check docstring is first.............................(no files to check)Skipped
Check Yaml...........................................(no files to check)Skipped
Debug Statements (Python)............................(no files to check)Skipped
Fix End of Files.........................................................Passed
Trim Trailing Whitespace.................................................Passed
black................................................(no files to check)Skipped
[detached HEAD 9bf8ba6b2] [ts-migrate][CRUD] Rename files from JS/JSX to TS/TSX
 3 files changed, 0 insertions(+), 0 deletions(-)
 rename superset-frontend/src/CRUD/{Field.jsx => Field.tsx} (100%)
 rename superset-frontend/src/CRUD/{Fieldset.jsx => Fieldset.tsx} (100%)
 rename superset-frontend/src/CRUD/{utils.js => utils.ts} (100%)
/Users/erik_ritter/repos/github.com/incubator-superset/superset-frontend

[Step 3 of 4] Fixing TypeScript errors...

forkTSServer
Logs in /var/folders/z4/_qft7mg12_980qwv4bsmblg40000gn/T/ts-migrate-log-7O4Yko
TypeScript version: 3.9.7
Initialized tsserver project in 215.457ms.
Start...
[strip-ts-ignore] Plugin 1 of 12. Start...
[strip-ts-ignore] Finished in 59.768ms.
[hoist-class-statics] Plugin 2 of 12. Start...
[hoist-class-statics] Finished in 2367.860ms.
[react-props] Plugin 3 of 12. Start...
[react-props] Finished in 35.451ms.
[react-class-state] Plugin 4 of 12. Start...
[react-class-state] Finished in 2.773ms.
[react-class-lifecycle-methods] Plugin 5 of 12. Start...
[react-class-lifecycle-methods] Finished in 43.427ms.
[react-default-props] Plugin 6 of 12. Start...
[react-default-props] Finished in 12.310ms.
[react-shape] Plugin 7 of 12. Start...
[react-shape] Finished in 0.690ms.
[declare-missing-class-properties] Plugin 8 of 12. Start...
[declare-missing-class-properties] Finished in 837.995ms.
[explicit-any] Plugin 9 of 12. Start...
[explicit-any] Finished in 348.799ms.
[eslint-fix] Plugin 10 of 12. Start...
npm run ts-migrate -- migrate <folder>

Fix TypeScript errors, using codemods

Positionals:
  folder                                                     [string] [required]

Options:
  -h, --help  Show help                                                [boolean]

Missing required argument: folder

Global Installation Support

Problem

When I install the ts-migrate tool globally via

yarn global add ts-migrate

The script will fail with the following:

/usr/local/bin/ts-migrate-full: line 78: ./node_modules/.bin/ts-migrate: No such file or directory

Solution

We should fix this by either:

  • warning that global installations are not supported (via CLI and/or in docs)
  • Resolving the binary file more explicitly instead of statically

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.