TypeScript 配置与工程化
这一篇深入 TypeScript 的配置和工程化:tsconfig.json 详解、
编译选项、与构建工具的集成、类型声明文件。
tsconfig.json 基础
配置文件结构
1{
2 "compilerOptions": {
3 // 编译选项
4 },
5 "include": [
6 "src/**/*"
7 ],
8 "exclude": [
9 "node_modules",
10 "dist"
11 ],
12 "extends": "./base.json",
13 "files": [
14 "src/index.ts"
15 ]
16}
配置继承
1// base.json
2{
3 "compilerOptions": {
4 "strict": true,
5 "target": "ES2020"
6 }
7}
8
9// tsconfig.json
10{
11 "extends": "./base.json",
12 "compilerOptions": {
13 "outDir": "./dist"
14 }
15}
编译选项详解
基础选项
1{
2 "compilerOptions": {
3 // 目标版本
4 "target": "ES2020",
5
6 // 模块系统
7 "module": "ESNext",
8
9 // 库文件
10 "lib": ["ES2020", "DOM"],
11
12 // 输出目录
13 "outDir": "./dist",
14
15 // 根目录
16 "rootDir": "./src",
17
18 // 输出文件
19 "outFile": "./dist/bundle.js"
20 }
21}
类型检查选项
1{
2 "compilerOptions": {
3 // 严格模式
4 "strict": true,
5
6 // 不允许隐式 any
7 "noImplicitAny": true,
8
9 // 严格的 null 检查
10 "strictNullChecks": true,
11
12 // 严格的函数类型检查
13 "strictFunctionTypes": true,
14
15 // 严格的 bind/call/apply 检查
16 "strictBindCallApply": true,
17
18 // 严格的属性初始化检查
19 "strictPropertyInitialization": true,
20
21 // 不允许 this 隐式 any
22 "noImplicitThis": true,
23
24 // 总是使用严格模式
25 "alwaysStrict": true,
26
27 // 不允许未使用的局部变量
28 "noUnusedLocals": true,
29
30 // 不允许未使用的参数
31 "noUnusedParameters": true,
32
33 // 不允许隐式返回
34 "noImplicitReturns": true,
35
36 // 不允许 fallthrough case
37 "noFallthroughCasesInSwitch": true
38 }
39}
模块解析选项
1{
2 "compilerOptions": {
3 // 模块解析策略
4 "moduleResolution": "node",
5
6 // 基础路径
7 "baseUrl": ".",
8
9 // 路径映射
10 "paths": {
11 "@/*": ["src/*"],
12 "utils/*": ["src/utils/*"]
13 },
14
15 // 根目录
16 "rootDirs": ["src", "generated"],
17
18 // 类型根目录
19 "typeRoots": ["./node_modules/@types"],
20
21 // 类型声明文件
22 "types": ["node", "jest"]
23 }
24}
输出选项
1{
2 "compilerOptions": {
3 // 生成声明文件
4 "declaration": true,
5
6 // 声明文件输出目录
7 "declarationDir": "./types",
8
9 // 生成 source map
10 "sourceMap": true,
11
12 // 生成内联 source map
13 "inlineSourceMap": true,
14
15 // 生成声明文件的 source map
16 "declarationMap": true,
17
18 // 移除注释
19 "removeComments": true,
20
21 // 不生成输出文件
22 "noEmit": true,
23
24 // 增量编译
25 "incremental": true,
26
27 // TS 构建信息文件
28 "tsBuildInfoFile": "./.tsbuildinfo"
29 }
30}
其他选项
1{
2 "compilerOptions": {
3 // 允许 JavaScript 文件
4 "allowJs": true,
5
6 // 检查 JavaScript 文件
7 "checkJs": true,
8
9 // JSX 模式
10 "jsx": "react",
11
12 // 实验性装饰器
13 "experimentalDecorators": true,
14
15 // 发出装饰器元数据
16 "emitDecoratorMetadata": true,
17
18 // 跳过库文件类型检查
19 "skipLibCheck": true,
20
21 // 强制文件大小写一致
22 "forceConsistentCasingInFileNames": true,
23
24 // 解析 JSON 模块
25 "resolveJsonModule": true,
26
27 // 隔离模块
28 "isolatedModules": true
29 }
30}
与构建工具集成
Webpack
1// webpack.config.js
2module.exports = {
3 entry: './src/index.ts',
4 module: {
5 rules: [
6 {
7 test: /\.tsx?$/,
8 use: 'ts-loader',
9 exclude: /node_modules/
10 }
11 ]
12 },
13 resolve: {
14 extensions: ['.tsx', '.ts', '.js']
15 }
16};
1// tsconfig.json
2{
3 "compilerOptions": {
4 "target": "ES2020",
5 "module": "ESNext",
6 "lib": ["ES2020", "DOM"],
7 "jsx": "react",
8 "strict": true,
9 "esModuleInterop": true,
10 "skipLibCheck": true,
11 "forceConsistentCasingInFileNames": true
12 }
13}
Vite
1// vite.config.ts
2import { defineConfig } from 'vite';
3import react from '@vitejs/plugin-react';
4
5export default defineConfig({
6 plugins: [react()],
7 resolve: {
8 alias: {
9 '@': '/src'
10 }
11 }
12});
1// tsconfig.json
2{
3 "compilerOptions": {
4 "target": "ES2020",
5 "useDefineForClassFields": true,
6 "lib": ["ES2020", "DOM", "DOM.Iterable"],
7 "module": "ESNext",
8 "skipLibCheck": true,
9 "moduleResolution": "bundler",
10 "allowImportingTsExtensions": true,
11 "resolveJsonModule": true,
12 "isolatedModules": true,
13 "noEmit": true,
14 "jsx": "react-jsx",
15 "strict": true,
16 "noUnusedLocals": true,
17 "noUnusedParameters": true,
18 "noFallthroughCasesInSwitch": true
19 },
20 "include": ["src"],
21 "references": [{ "path": "./tsconfig.node.json" }]
22}
Rollup
1// rollup.config.js
2import typescript from '@rollup/plugin-typescript';
3
4export default {
5 input: 'src/index.ts',
6 output: {
7 file: 'dist/bundle.js',
8 format: 'cjs'
9 },
10 plugins: [
11 typescript({
12 tsconfig: './tsconfig.json'
13 })
14 ]
15};
类型声明文件
声明文件类型
1// 全局声明
2declare const API_URL: string;
3declare function myGlobalFunction(): void;
4
5// 模块声明
6declare module 'module-name' {
7 export interface MyType {
8 prop: string;
9 }
10}
11
12// 命名空间声明
13declare namespace MyNamespace {
14 export interface MyType {
15 prop: string;
16 }
17}
为第三方库创建类型声明
1// types/my-library.d.ts
2declare module 'my-library' {
3 export function doSomething(): void;
4 export interface Config {
5 api: string;
6 }
7}
扩展全局类型
1// types/global.d.ts
2declare global {
3 interface Window {
4 myCustomProperty: string;
5 }
6
7 namespace NodeJS {
8 interface ProcessEnv {
9 NODE_ENV: 'development' | 'production' | 'test';
10 API_URL: string;
11 }
12 }
13}
14
15export {};
模块扩展
1// 扩展 Express Request
2declare namespace Express {
3 interface Request {
4 user?: {
5 id: string;
6 name: string;
7 };
8 }
9}
项目结构
单项目结构
1project/
2├── src/
3│ ├── index.ts
4│ └── utils/
5├── dist/
6├── types/
7├── tsconfig.json
8└── package.json
多项目结构(Project References)
1// tsconfig.json
2{
3 "compilerOptions": {
4 "composite": true,
5 "declaration": true
6 },
7 "references": [
8 { "path": "./packages/core" },
9 { "path": "./packages/utils" }
10 ]
11}
1// packages/core/tsconfig.json
2{
3 "compilerOptions": {
4 "composite": true,
5 "declaration": true,
6 "outDir": "./dist"
7 }
8}
实际应用场景
开发环境配置
1// tsconfig.dev.json
2{
3 "extends": "./tsconfig.json",
4 "compilerOptions": {
5 "sourceMap": true,
6 "inlineSourceMap": true,
7 "noEmit": false
8 },
9 "include": ["src/**/*"]
10}
生产环境配置
1// tsconfig.prod.json
2{
3 "extends": "./tsconfig.json",
4 "compilerOptions": {
5 "removeComments": true,
6 "sourceMap": false,
7 "declaration": true
8 },
9 "exclude": ["**/*.test.ts", "**/*.spec.ts"]
10}
测试环境配置
1// tsconfig.test.json
2{
3 "extends": "./tsconfig.json",
4 "compilerOptions": {
5 "types": ["jest", "node"]
6 },
7 "include": ["src/**/*", "tests/**/*"]
8}
最佳实践
1. 使用严格模式
1{
2 "compilerOptions": {
3 "strict": true
4 }
5}
2. 配置路径别名
1{
2 "compilerOptions": {
3 "baseUrl": ".",
4 "paths": {
5 "@/*": ["src/*"]
6 }
7 }
8}
3. 启用增量编译
1{
2 "compilerOptions": {
3 "incremental": true,
4 "tsBuildInfoFile": "./.tsbuildinfo"
5 }
6}
4. 分离配置
1// tsconfig.base.json
2{
3 "compilerOptions": {
4 "strict": true,
5 "target": "ES2020"
6 }
7}
8
9// tsconfig.json
10{
11 "extends": "./tsconfig.base.json",
12 "compilerOptions": {
13 "outDir": "./dist"
14 }
15}
小结
TypeScript 的配置和工程化:
- tsconfig.json:核心配置文件,控制编译行为
- 编译选项:目标版本、模块系统、类型检查、输出选项
- 构建工具集成:Webpack、Vite、Rollup 等
- 类型声明文件:为 JavaScript 库提供类型定义
- 项目结构:单项目和多项目结构
在实际开发中:
- 使用严格模式提高代码质量
- 配置路径别名简化导入
- 启用增量编译提高构建速度
- 分离不同环境的配置
- 为第三方库创建类型声明