Skip to content

Commit 1ce0457

Browse files
vdiezclaude
andcommitted
Use type imports for type-only imports
Add `type` modifier to imports that are only used for type checking. This improves tree-shaking and makes it clear which imports are only used at compile time. Also update CLAUDE.md with this convention. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent f9663c2 commit 1ce0457

21 files changed

+164
-89
lines changed

CLAUDE.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,18 @@ logWithPrefix(LogLevel.INFO, 'ComponentName', 'message');
8181

8282
Prettier config: 100 char width, trailing commas, single quotes, LF line endings. Pre-commit hook auto-formats staged files.
8383

84+
### Pre-commit Checks
85+
86+
Before committing, verify there are no TypeScript errors and no unused exports:
87+
88+
```bash
89+
npx tsc --noEmit -p tsconfig.json
90+
npx tsc --noEmit -p test/unit/tsconfig.json
91+
npx knip
92+
```
93+
94+
Note: `test/integration/tsconfig.json` requires running `npm install` in `test/integration/` first, as it depends on the build artifact.
95+
8496
### External Tools
8597

8698
- Use `gh` CLI to interact with GitHub (issues, PRs, etc.)
@@ -101,6 +113,23 @@ import path from 'path';
101113
import { spawn } from 'child_process';
102114
```
103115

116+
### Type Imports
117+
118+
Use `import type` when importing types only. This helps with tree-shaking and makes it clear which imports are only used for type checking:
119+
120+
```typescript
121+
// When all imports are types, use import type
122+
import type { ScannerProperties, ScanOptions } from './types';
123+
import type { ChildProcess, SpawnOptions } from 'node:child_process';
124+
125+
// When mixing types and values, use inline type modifier
126+
import { type ChildProcess, spawn } from 'node:child_process';
127+
import { type ScannerProperties, ScannerProperty } from './types';
128+
129+
// Incorrect: importing types as regular imports
130+
import { ScannerProperties, ScanOptions } from './types';
131+
```
132+
104133
## Testing
105134

106135
### Unit Tests

src/file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import tarStream from 'tar-stream';
2525
import zlib from 'node:zlib';
2626
import { SONAR_CACHE_DIR, UNARCHIVE_SUFFIX } from './constants';
2727
import { LogLevel, log } from './logging';
28-
import { CacheFileData, ScannerProperties, ScannerProperty } from './types';
28+
import { type CacheFileData, type ScannerProperties, ScannerProperty } from './types';
2929

3030
export interface FileDeps {
3131
existsSync: typeof fs.existsSync;

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
*/
2020
import { scan } from './scan';
21-
import { ScanOptions } from './types';
21+
import type { ScanOptions } from './types';
2222

2323
export { scan };
2424

src/java.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020
import fs from 'node:fs';
2121
import path from 'node:path';
22-
import semver, { SemVer } from 'semver';
22+
import semver, { type SemVer } from 'semver';
2323
import {
2424
API_OLD_VERSION_ENDPOINT,
2525
API_V2_JRE_ENDPOINT,
@@ -37,10 +37,10 @@ import {
3737
import { LogLevel, log } from './logging';
3838
import { download, fetch } from './request';
3939
import {
40-
AnalysisJreMetaData,
41-
AnalysisJresResponseType,
40+
type AnalysisJreMetaData,
41+
type AnalysisJresResponseType,
4242
CacheStatus,
43-
ScannerProperties,
43+
type ScannerProperties,
4444
ScannerProperty,
4545
} from './types';
4646

src/process.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,11 @@ const defaultProcessDeps: ProcessProcessDeps = {
4040
},
4141
};
4242

43+
type ExecAsyncFn = (command: string) => Promise<{ stdout: string; stderr: string }>;
44+
4345
export interface ProcessModuleDeps {
4446
processDeps?: ProcessProcessDeps;
45-
execAsyncFn?: typeof execAsync;
47+
execAsyncFn?: ExecAsyncFn;
4648
}
4749

4850
/**

src/properties.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ import { getArch, getSupportedOS } from './platform';
4545
import { version } from './version';
4646
import {
4747
CacheStatus,
48-
CliArgs,
49-
PackageJson,
50-
ScanOptions,
51-
ScannerProperties,
48+
type CliArgs,
49+
type PackageJson,
50+
type ScanOptions,
51+
type ScannerProperties,
5252
ScannerProperty,
5353
} from './types';
5454

src/proxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020
import { URL } from 'node:url';
2121
import { LogLevel, log } from './logging';
22-
import { ScannerProperties, ScannerProperty } from './types';
22+
import { type ScannerProperties, ScannerProperty } from './types';
2323

2424
export function getProxyUrl(properties: ScannerProperties): URL | undefined {
2525
const proxyHost = properties[ScannerProperty.SonarScannerProxyHost];

src/request.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* along with this program; if not, write to the Free Software Foundation,
1818
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
*/
20-
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
20+
import axios, { type AxiosInstance, type AxiosRequestConfig } from 'axios';
2121
import fs from 'node:fs';
2222
import { HttpProxyAgent, HttpsProxyAgent } from 'hpagent';
2323
import https from 'node:https';
@@ -26,7 +26,7 @@ import * as stream from 'node:stream';
2626
import { promisify } from 'node:util';
2727
import { LogLevel, log } from './logging';
2828
import { getProxyUrl } from './proxy';
29-
import { ScannerProperties, ScannerProperty } from './types';
29+
import { type ScannerProperties, ScannerProperty } from './types';
3030

3131
const finished = promisify(stream.finished);
3232

src/scan.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
fetchScannerEngine as defaultFetchScannerEngine,
3535
runScannerEngine as defaultRunScannerEngine,
3636
} from './scanner-engine';
37-
import { CliArgs, ScanOptions, ScannerProperty } from './types';
37+
import { type CliArgs, type ScanOptions, ScannerProperty } from './types';
3838
import { version } from './version';
3939

4040
export interface ScanDeps {

src/scanner-cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* along with this program; if not, write to the Free Software Foundation,
1818
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
*/
20-
import { AxiosRequestConfig } from 'axios';
20+
import type { AxiosRequestConfig } from 'axios';
2121
import { spawn as nodeSpawn } from 'node:child_process';
2222
import fs from 'node:fs';
2323
import path from 'node:path';
@@ -34,7 +34,7 @@ import { LogLevel, log } from './logging';
3434
import { isLinux, isMac, isWindows } from './platform';
3535
import { proxyUrlToJavaOptions } from './proxy';
3636
import { download } from './request';
37-
import { ScanOptions, ScannerProperties, ScannerProperty } from './types';
37+
import { type ScanOptions, type ScannerProperties, ScannerProperty } from './types';
3838

3939
export interface ScannerCliFsDeps {
4040
exists: (path: string) => Promise<boolean>;
@@ -47,7 +47,7 @@ export interface ScannerCliProcessDeps {
4747
env: NodeJS.ProcessEnv;
4848
}
4949

50-
export type SpawnFn = typeof nodeSpawn;
50+
type SpawnFn = typeof nodeSpawn;
5151

5252
const defaultFsDeps: ScannerCliFsDeps = {
5353
exists: async (filePath: string) => {

0 commit comments

Comments
 (0)