解决 typescript node tsx 的兼容问题

发布时间 2023-12-30 21:36:36作者: Mitchell_C

# 问题
在项目中使用 typescript + tsx + node 存在各种兼容问题,包括:

- >[esbuild Error]: Top-level await is currently not supported with the "cjs" output format
- >Cannot find module 'X'. Did you mean to set the 'moduleResolution' option to 'nodenext', or to add aliases to the 'paths' option?
- >X is a type and must be imported using a type-only import when 'verbatimModuleSyntax' is enabled
- >An 'export default' must reference a value when 'verbatimModuleSyntax' is enabled, but 'X' only refers to a type

# 配置

配置下述文件后,以上问题得以解决。
# package.json
在 `package.json` 中添加:`"type": "module"` ,
在 `"script"` 中使用 `tsx`,例如:`"dev": "npx tsx src/app.ts"`

# tsconfig.json
在 `tsconfig.json` 中设置如下内容:
```json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"allowImportingTsExtensions": true,
"customConditions": ["module"],
"allowArbitraryExtensions": true,
"noEmit": true,
"verbatimModuleSyntax": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
}
```

# import、export

使用 `export type X = {}` 导出 TypeScript Type,例如:

```typescript
export type X = {
item_1: string,
item_2: string
}
```
同样,使用 `import type { X } from path` 导入 TypeScript Type,例如:
```typescript
import type { X } from './types'
```

导入和导出第三方库使用 `ESM` 形式,例如:
```typescript
import express from 'express'
```

```typescript
export default X
```

# 参考
* [TypeScript: Modules - Theory](https://www.typescriptlang.org/docs/handbook/modules/theory.html)
* [TypeScript: Modules - Choosing Compiler Options](https://www.typescriptlang.org/docs/handbook/modules/guides/choosing-compiler-options.html)
* [export default type](https://github.com/microsoft/TypeScript/issues/41409)
* ["... is a type and must be imported using a type-only import ..." should have a quick fix](https://github.com/microsoft/TypeScript/issues/52444)
* [ERROR: Top-level await is currently not supported with the "cjs" output format](https://github.com/privatenumber/tsx/discussions/137)