Skip to content
On this page

TypeScript 配置与编译

TypeScript 的配置和编译过程是开发流程中的关键部分,通过合理的配置可以优化开发体验和代码质量。

tsconfig.json 配置文件

基本配置结构

json
{
  "compilerOptions": {
    /* 基本选项 */
    "target": "es5",                          /* 指定 ECMAScript 目标版本 */
    "module": "commonjs",                     /* 指定模块代码生成方式 */
    "lib": ["es2017", "dom"],                /* 指定要包含在编译中的库文件 */
    "allowJs": true,                          /* 允许编译 JavaScript 文件 */
    "checkJs": true,                          /* 报告 JavaScript 文件中的错误 */
    "jsx": "preserve",                        /* 指定 JSX 代码生成方式 */
    "declaration": true,                      /* 生成相应的 .d.ts 文件 */
    "declarationMap": true,                   /* 为每个相应的 .d.ts 文件生成源映射 */
    "sourceMap": true,                        /* 生成相应的 .map 文件 */
    "outFile": "./dist/bundle.js",            /* 将输出连接到单个文件 */
    "outDir": "./dist",                       /* 指定输出目录 */
    "rootDir": "./src",                       /* 指定输入文件的根目录 */
    "removeComments": true,                   /* 不将注释输出到生成的代码中 */
    "noEmit": true,                           /* 不生成输出文件 */
    "importHelpers": true,                    /* 从 tslib 导入帮助程序 */
    "downlevelIteration": true,               /* 为迭代器提供完全支持 */

    /* 严格类型检查选项 */
    "strict": true,                           /* 启用所有严格类型检查选项 */
    "noImplicitAny": true,                    /* 在表达式和声明中具有隐含的 any 类型时报错 */
    "strictNullChecks": true,                 /* 启用严格的空值检查 */
    "strictFunctionTypes": true,              /* 启用严格的函数类型检查 */
    "strictBindCallApply": true,              /* 启用严格的 bind、call 和 apply 方法检查 */
    "strictPropertyInitialization": true,     /* 启用严格的属性初始化检查 */
    "noImplicitThis": true,                   /* 当 this 表达式的值为 any 类型时引发错误 */
    "alwaysStrict": true,                     /* 以严格模式解析并为每个源文件生成 "use strict" 指令 */

    /* 额外检查 */
    "noUnusedLocals": true,                   /* 报告未使用的本地变量的错误 */
    "noUnusedParameters": true,               /* 报告未使用的参数的错误 */
    "noImplicitReturns": true,                /* 当函数中没有返回语句返回值时报告错误 */
    "noFallthroughCasesInSwitch": true,       /* 报告 switch 语句中跌落情况的错误 */

    /* 模块解析选项 */
    "moduleResolution": "node",               /* 指定模块解析策略 */
    "baseUrl": "./",                          /* 解析非相对模块名的基础目录 */
    "paths": {},                              /* 模块名到基于 baseUrl 的路径映射 */
    "rootDirs": [],                           /* 运行时模块合并的基础目录列表 */
    "typeRoots": [],                          /* 包含类型定义的目录列表 */
    "types": ["node", "jest"],                /* 要包含的类型声明文件 */
    "allowSyntheticDefaultImports": true,     /* 允许从没有默认导出的模块中默认导入 */
    "esModuleInterop": true,                  /* 启用生成的模块辅助程序的 ES 模块互操作 */
    "preserveSymlinks": true,                 /* 不解析符号链接的实参 */

    /* Source Map 选项 */
    "sourceRoot": "",                         /* 指定调试器应该定位 TypeScript 文件的位置 */
    "mapRoot": "",                            /* 指定调试器应该定位映射文件的位置 */
    "inlineSourceMap": true,                  /* 生成单个包含源映射的文件 */
    "inlineSources": true,                    /* 在单个文件中发出源代码 */

    /* 实验性选项 */
    "experimentalDecorators": true,           /* 启用对装饰器的实验性支持 */
    "emitDecoratorMetadata": true             /* 启用对装饰器的元数据的实验性支持 */
  },
  "include": [
    "src/**/*"                                /* 包含的文件模式 */
  ],
  "exclude": [
    "node_modules",                          /* 排除的文件模式 */
    "**/*.spec.ts"
  ],
  "extends": "./tsconfig.base.json"          /* 继承基础配置 */
}

常用配置示例

Node.js 项目配置

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "lib": ["ES2020"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "removeComments": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "noImplicitThis": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

React 项目配置

json
{
  "compilerOptions": {
    "target": "ES2020",
    "lib": ["dom", "dom.iterable", "ES2020"],
    "module": "ESNext",
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "strictNullChecks": true
  },
  "include": ["src"]
}

库项目配置

json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM"],
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "stripInternal": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}

编译选项详解

目标版本 (target)

json
{
  "compilerOptions": {
    "target": "ES3"      /* ES3 (默认) */
    // "target": "ES5"   /* ES5 */
    // "target": "ES2015" /* ES2015 */
    // "target": "ES2016" /* ES2016 */
    // "target": "ES2017" /* ES2017 */
    // "target": "ES2018" /* ES2018 */
    // "target": "ES2019" /* ES2019 */
    // "target": "ES2020" /* ES2020 */
    // "target": "ES2021" /* ES2021 */
    // "target": "ES2022" /* ES2022 */
    // "target": "ESNext" /* 最新支持的 ES 版本 */
  }
}

模块系统 (module)

json
{
  "compilerOptions": {
    "module": "CommonJS"    /* CommonJS (Node.js) */
    // "module": "AMD"      /* AMD (Require.js) */
    // "module": "UMD"      /* UMD (通用模块定义) */
    // "module": "System"   /* SystemJS */
    // "module": "ES6"      /* ES6 模块 */
    // "module": "ES2015"   /* ES2015 模块 */
    // "module": "ES2020"   /* ES2020 模块 */
    // "module": "ESNext"   /* 最新 ES 模块 */
  }
}

严格类型检查

json
{
  "compilerOptions": {
    "strict": true,                           /* 启用所有严格类型检查选项 */
    "noImplicitAny": true,                    /* 隐含 any 类型时报错 */
    "strictNullChecks": true,                 /* 严格空值检查 */
    "strictFunctionTypes": true,              /* 严格函数类型检查 */
    "strictBindCallApply": true,              /* 严格 bind/call/apply 检查 */
    "strictPropertyInitialization": true,     /* 严格属性初始化检查 */
    "noImplicitThis": true,                   /* this 为 any 时报错 */
    "alwaysStrict": true                      /* 以严格模式解析 */
  }
}

路径映射配置

基础路径映射

json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@utils/*": ["src/utils/*"],
      "@assets/*": ["src/assets/*"],
      "@api/*": ["src/api/*"],
      "@types": ["src/types/index.d.ts"]
    }
  }
}

复杂路径映射

json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "react": ["./node_modules/@types/react"],
      "@/*": ["src/*"],
      "@shared/*": ["shared/*", "src/shared/*"],
      "config": ["src/config/index.ts"]
    }
  }
}

编译命令

基本编译命令

bash
# 使用 tsconfig.json 编译整个项目
tsc

# 指定配置文件编译
tsc -p tsconfig.json

# 编译特定文件
tsc src/main.ts

# 编译并监视文件变化
tsc --watch

# 指定输出目录
tsc --outDir dist

# 指定目标版本
tsc --target ES2020

# 启用严格模式
tsc --strict

常用编译选项

bash
# 生成声明文件
tsc --declaration

# 生成源映射文件
tsc --sourceMap

# 启用装饰器支持
tsc --experimentalDecorators

# 启用装饰器元数据
tsc --emitDecoratorMetadata

# 检查 JS 文件
tsc --allowJs --checkJs

# 不输出文件,只进行类型检查
tsc --noEmit

# 生成项目引用
tsc --build tsconfig.json

项目引用

基础项目引用配置

// tsconfig.base.json

json
{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "strict": true
  }
}

// tsconfig.client.json

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist/client"
  },
  "include": ["./client/**/*"],
  "references": [
    { "path": "./tsconfig.shared.json" }
  ]
}

// tsconfig.server.json

json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./dist/server"
  },
  "include": ["./server/**/*"],
  "references": [
    { "path": "./tsconfig.shared.json" }
  ]
}

类型声明文件

全局类型声明

// src/types/global.d.ts

typescript
declare global {
  interface Window {
    myCustomProperty: string;
  }
  
  var process: {
    env: {
      NODE_ENV: 'development' | 'production';
    };
  };
}

export {}; // 确保这是一个模块

模块声明

// src/types/module.d.ts

typescript
declare module "my-module" {
  export interface MyModuleConfig {
    version: number;
    enabled: boolean;
  }
  
  export class MyModule {
    constructor(config: MyModuleConfig);
    doSomething(): void;
  }
}

编译性能优化

增量编译

json
{
  "compilerOptions": {
    "incremental": true,
    "tsBuildInfoFile": "./.tsbuildinfo"
  }
}

缓存配置

json
{
  "compilerOptions": {
    "incremental": true,
    "composite": true,
    "tsBuildInfoFile": ".tsbuildinfo"
  }
}

环境特定配置

开发环境配置

// tsconfig.dev.json

json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "sourceMap": true,
    "inlineSourceMap": false,
    "declaration": false,
    "declarationMap": false
  }
}

生产环境配置

// tsconfig.prod.json

json
{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "removeComments": true,
    "sourceMap": false
  }
}

小结

TypeScript 的配置和编译系统提供了丰富的选项来控制代码的生成和类型检查过程。通过合理配置 tsconfig.json 文件,我们可以优化开发体验、提高代码质量,并满足不同项目的需求。理解各种编译选项的含义和用途对于高效使用 TypeScript 至关重要。