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

Convert implicit type imports to explicit types (using ts-morph) #3

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# type-import-codemod

Combines your type and value imports together into a single statement, using [Typescript 4.5's type modifier syntax](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#type-on-import-names).
Combines your type and value imports together into a single statement, using [Typescript 4.5's type modifier syntax](https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/#type-on-import-names). It will also find type imports which have not been marked as types to be converted into explicit type imports

Before:

```ts
import React, { useState } from 'react';
import type { ComponentProps } from 'react';
import type { AnotherType } from './types';
import { AnotherType } from './types';
```

After:

```ts
import React, { useState, type ComponentProps } from 'react';
import type { AnotherType } from './types';
import { type AnotherType } from './types';
```

Note, the type import from react was placed at the end of the value imports, and the import from './types' was not changed. Type imports will not be modified, unless they can be combined into another import statement, as shown for the react imports.
Note, the type import from react was placed at the end of the value imports, and the import from './types' was not changed.

## Installation

Expand All @@ -27,14 +27,14 @@ npm install type-import-codemod

## Usage

This is a [jscodeshift](https://www.npmjs.com/package/jscodeshift) transform, with a simple wrapper script to call jscodeshift for you. You should specify the file/directories to run the codemod on, as well as any other [jscodeshift arguments](https://github.com/facebook/jscodeshift#usage-cli) that you need. The only argument added by this package is the transform.
This is a CLI that wraps a [ts-morph](https://github.com/dsherret/ts-morph/tree/latest/packages/ts-morph) transform. One or more globs and/or file paths are required, to specify which files to run against. You should also provide a path to your tsconfig.json if it is not located at your project root or is named something other than tsconfig.json.

For example:

```shell
npx type-import-codemod src --extensions=tsx --parser=tsx
npx type-import-codemod --project="./custom-tsconfig.json" src/**/*.ts
```

This will run the transform on all files ending in `.tsx` in the `./src` directory, using the correct parser.

**Note**: Be sure to commit changes to your files before running this tool, as it can potentially cause a lot of changes. If in doubt, use the `--dry` and `--print` flags to see what effect the transform will have, before it makes changes to your files.
**Note**: Be sure to commit changes to your files before running this tool, as it can potentially cause a lot of changes. If in doubt, use the `--dry-run` flag to see what effect the transform will have, before it makes changes to your files.
24 changes: 0 additions & 24 deletions bin/type-import-codemod.js

This file was deleted.

46 changes: 46 additions & 0 deletions bin/type-import-codemod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/usr/bin/env node --loader tsx --no-warnings

import { resolve } from 'path';
import chalk from 'chalk';
import { program, Option } from 'commander';
import transform from '../src/transform.js';
import packageConfig from '../package.json' assert { type: 'json' };

const sourceGlobs = [];
const version = packageConfig.version;

program
.version(version)
.arguments('<globs...>')
.action((args) => {
sourceGlobs.push(...args.filter((arg) => arg && typeof arg === 'string'));
})
.option('-d, --dry-run', 'write output to stdout instead of overwriting files')
.addOption(new Option('-p, --project <path>', 'path to tsconfig.json').default('./tsconfig.json'))
.parse(process.argv);

const options = program.opts();
const dryRun = options.dryRun === true;
const project = options.project;
const globs = program.args;
const tsconfigPath = resolve(process.cwd(), project);

try {
await import(tsconfigPath);
} catch (err) {
const message = `type-import-codemod --project ${tsconfigPath} is not a valid tsconfig.json file`;
console.error(chalk.red(message));
process.exit(1);
}

try {
transform({
dryRun,
globs,
tsconfigPath,
});
} catch (err) {
console.error(chalk.red('type-import-codemod: '), err.message);
console.error(err);
process.exit(1);
}
Loading