TypeScript的配置文件tsconfig.json看起来简单,但里面的配置项很多,很多人不知道怎么配置才合理。本文详细讲解TypeScript 4.0的配置,从基础配置到高级配置,包括编译选项、类型检查、模块解析、源码映射、严格模式等,每个配置项都讲清楚作用和推荐值,帮你写出合理的tsconfig配置。

一、为什么要认真配置tsconfig

很多人用TypeScript,tsconfig.json就是用脚手架自动生成的,从来没改过,甚至不知道里面的配置是什么意思。这其实是不对的。

tsconfig.json是TypeScript项目的配置文件,它决定了:

  • TypeScript怎么编译你的代码
  • 启用哪些类型检查,检查的严格程度
  • 编译输出什么格式(ES5/ES6/ES2020,CommonJS/ES Module)
  • 怎么解析模块
  • 要不要生成source map
  • 哪些文件要编译,哪些要排除

配置不合理,会导致各种问题:

  • 类型检查太松,起不到TypeScript的作用,和写JavaScript差不多
  • 类型检查太严,到处报错,开发体验差
  • 编译输出格式不对,在目标环境运行不了
  • 模块解析有问题,找不到模块
  • 没有source map,调试困难

所以,认真配置tsconfig是很重要的。它能让TypeScript更好地为你服务,既保证类型安全,又有良好的开发体验。

TypeScript 4.0在2020年8月发布,带来了一些新特性和配置项。本文基于TypeScript 4.0,详细讲解tsconfig的配置。

二、tsconfig.json基础

1. 什么是tsconfig.json

tsconfig.json是TypeScript项目的配置文件,放在项目根目录下。当你运行tsc命令(不带参数)的时候,TypeScript会自动查找当前目录下的tsconfig.json,按照里面的配置来编译项目。

tsconfig.json是一个JSON文件,里面包含了各种编译选项。它还可以指定哪些文件要编译、哪些要排除。

2. 最简单的tsconfig

最简单的tsconfig.json可以只有一个空对象{},这时候TypeScript会用默认配置编译当前目录下的所有.ts文件。但默认配置比较宽松,不推荐在实际项目中使用。

一个基础的tsconfig大概长这样:

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "commonjs",
    "strict": true,
    "outDir": "./dist",
    "rootDir": "./src"
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

下面我们就来详细讲解每个配置项。

3. tsconfig的顶层配置

tsconfig.json有几个顶层配置:

  • compilerOptions:编译选项,最核心的部分,下面详细讲
  • include:指定要编译的文件列表,支持通配符
  • exclude:指定要排除的文件列表,支持通配符
  • files:指定要编译的具体文件列表,不支持通配符
  • extends:继承另一个tsconfig配置,用于配置复用
  • references:项目引用,用于大型项目的多项目构建

一般项目用includeexclude就够了,files用得少。extendsreferences在大型项目或monorepo中用得多。

三、基础编译选项

先讲最基础、最常用的编译选项。

1. target

target指定编译后的JavaScript版本,也就是TypeScript把代码编译成哪个版本的JavaScript。

可选值:ES3ES5ES6/ES2015ES2016ES2017ES2018ES2019ES2020ESNext

  • ES3:最老的版本,兼容性最好,但很多新语法要编译成复杂的兼容代码,输出文件大
  • ES5:兼容性好,支持所有现代浏览器和Node.js,是最常用的target
  • ES2015+:支持更多新语法,输出代码更简洁,但需要运行环境支持
  • ESNext:最新的版本,包含还在提案中的特性,不稳定

推荐值

  • 浏览器项目:如果需要兼容老浏览器,用ES5;如果只支持现代浏览器,可以用ES2017或更高
  • Node.js项目:根据Node.js版本选择,Node.js 12+支持ES2019,Node.js 14+支持ES2020
  • 库项目:建议用ES5,兼容性最好

TypeScript 4.0默认的target是ES3,但实际项目中不建议用ES3,太老了。

2. module

module指定编译后的模块系统,也就是用什么方式组织代码的导入导出。

可选值:NoneCommonJSAMDSystemUMDES6/ES2015ES2020ESNextNone

  • CommonJS:Node.js的模块系统,用requiremodule.exports,Node.js项目用这个
  • ES6/ES2015:ES模块系统,用importexport,浏览器项目或配合打包工具用这个
  • UMD:通用模块定义,同时支持CommonJS和AMD,还能全局变量引入,适合在浏览器和Node.js都能用的库
  • AMD:异步模块定义,主要用于RequireJS,现在用得少了
  • System:SystemJS的模块格式,用得少

推荐值

  • Node.js项目:CommonJS
  • 浏览器项目(用webpack/Vite等打包工具):ESNextES2020,让打包工具处理模块
  • 库项目(同时支持浏览器和Node.js):UMD,或者分别输出CommonJS和ES Module两种格式

注意:moduletarget是独立的,target决定语法版本,module决定模块系统。比如可以target是ES5,module是ES2015。

3. outDir

outDir指定编译输出的目录,编译后的.js文件会输出到这个目录下,保持和源文件相同的目录结构。

比如:

"outDir": "./dist"

源文件src/index.ts会编译到dist/index.js

如果不指定outDir,编译后的.js文件会和源文件在同一个目录下,这会导致源码目录混乱,不推荐。实际项目中一定要指定outDir。

4. rootDir

rootDir指定源文件的根目录,用来控制输出目录的结构。

比如源文件都在src目录下,指定rootDir: "./src",那么编译后的文件结构就是相对于src的。如果不指定rootDir,TypeScript会自动计算所有输入文件的最长公共路径作为rootDir。

一般情况下,rootDir和include配合使用,指定rootDir: "./src"include: ["src/*/"],这样输出目录结构清晰。

5. strict

strict是TypeScript严格模式的总开关,开启后会启用一系列严格的类型检查选项。

strict: true相当于同时开启以下选项:

  • noImplicitAny:不允许隐式的any类型
  • strictNullChecks:严格的null检查
  • strictFunctionTypes:严格的函数类型检查
  • strictBindCallApply:严格的bind/call/apply检查
  • strictPropertyInitialization:严格的属性初始化检查
  • noImplicitThis:不允许隐式的this类型
  • alwaysStrict:在每个文件顶部添加use strict

推荐值true。强烈建议开启严格模式,这是TypeScript类型安全的核心。不开启严格模式,TypeScript的类型检查会松很多,很多错误检查不出来,相当于白用TypeScript了。

刚开始用严格模式可能会觉得到处报错,不习惯,但坚持用一段时间,你会发现代码质量提升了很多,很多潜在的bug在编译阶段就被发现了。

6. esModuleInterop

esModuleInterop启用ES模块互操作性,让TypeScript在编译CommonJS模块的时候,更好地处理ES模块和CommonJS模块的互操作。

具体来说,开启后:

  • 可以用import React from 'react'这样的默认导入,来导入CommonJS模块(React是CommonJS模块)
  • 编译时会添加importDefaultimportStar辅助函数,正确处理默认导入和命名空间导入

如果不开启,导入CommonJS模块的时候,需要用import * as React from 'react',比较麻烦,而且有些情况下会有问题。

推荐值true。现在的项目基本都开启这个选项,尤其是用React等CommonJS模块的时候。

7. skipLibCheck

skipLibCheck跳过对声明文件(.d.ts)的类型检查。

TypeScript在编译的时候,会检查所有引入的声明文件,包括node_modules里的第三方库的声明文件。但有些第三方库的声明文件写得不规范,会有类型错误,导致你的项目编译报错,虽然这些错误不是你代码的问题。

开启skipLibCheck: true后,TypeScript会跳过对声明文件的检查,只检查你自己的代码,避免因为第三方库的声明文件问题导致编译失败。

推荐值true。实际项目中基本都开启,不然很容易因为第三方库的声明文件问题报错。当然,这也意味着第三方库的类型错误不会被检查到,但通常这不是问题,因为第三方库的类型错误不影响你的代码。

8. forceConsistentCasingInFileNames

forceConsistentCasingInFileNames强制文件名大小写一致。

在大小写不敏感的文件系统(如Windows、macOS默认)上,import './Foo'import './foo'可能都能找到文件,但在大小写敏感的文件系统(如Linux)上,这两个是不同的文件。如果你的代码里大小写不一致,在Linux上部署的时候可能会出问题。

开启这个选项后,TypeScript会检查导入的文件名大小写是否和实际文件一致,不一致就报错,避免跨平台问题。

推荐值true。建议开启,避免跨平台的大小写问题。

四、类型检查选项

接下来讲类型检查相关的选项,这些选项决定了TypeScript检查的严格程度。

1. noImplicitAny

noImplicitAny不允许隐式的any类型。

当TypeScript无法推断出一个变量或参数的类型时,它会默认给一个any类型。开启noImplicitAny后,这种情况会报错,要求你显式指定类型。

比如:

// 报错:参数'a'隐式具有'any'类型
function add(a, b) {
  return a + b;
}

// 正确:显式指定类型
function add(a: number, b: number): number {
  return a + b;
}

推荐值true(strict模式下自动开启)。不允许隐式any,能强制你写类型注解,提升代码的类型安全。

2. strictNullChecks

strictNullChecks严格的null和undefined检查。

不开启的时候,null和undefined可以赋值给任何类型,比如:

let name: string = null; // 不报错

开启后,null和undefined不能赋值给其他类型,必须显式处理:

let name: string = null; // 报错
let name: string | null = null; // 正确

开启strictNullChecks后,你必须显式处理可能为null的情况,比如用可选链?.、空值合并??、类型守卫等,能避免很多空指针错误。

推荐值true(strict模式下自动开启)。强烈建议开启,这是避免空指针错误的最有效手段。

3. noUnusedLocals

noUnusedLocals不允许有未使用的局部变量。

开启后,如果声明了一个局部变量但没有使用,会报错:

function foo() {
  const a = 1; // 报错:'a'已声明但从未使用
  return 1;
}

推荐值true。能帮你清理无用代码,保持代码整洁。但有时候开发过程中会临时声明一些变量还没用到,这时候会报错比较烦,可以在开发阶段暂时关闭,上线前开启。

4. noUnusedParameters

noUnusedParameters不允许有未使用的函数参数。

开启后,函数参数如果没用到会报错:

// 报错:'b'已声明但从未使用
function foo(a: number, b: number) {
  return a;
}

如果参数确实不需要,可以用下划线前缀_b,TypeScript会忽略以下划线开头的未使用参数。

推荐值true。和noUnusedLocals一样,能帮你清理无用代码。但有些接口实现的参数必须保留,用下划线前缀就行。

5. noImplicitReturns

noImplicitReturns不允许函数有隐式的返回值不一致。

开启后,函数的所有分支都必须有返回值,或者都没有返回值:

// 报错:函数缺少结束返回语句,返回类型不包含'undefined'
function foo(a: number): number {
  if (a > 0) {
    return 1;
  }
  // 这里没有return
}

推荐值true。能避免函数某些分支忘记return的bug。

6. noFallthroughCasesInSwitch

noFallthroughCasesInSwitch不允许switch语句中的case穿透。

开启后,switch的每个case都必须有break、return或throw,不能穿透到下一个case:

// 报错:case穿透
switch (a) {
  case 1:
    console.log(1);
    // 没有break
  case 2:
    console.log(2);
    break;
}

如果你确实需要穿透,要加注释// fallthrough,TypeScript会忽略。

推荐值true。switch穿透是常见的bug来源,开启后能避免。

7. allowUnreachableCode

allowUnreachableCode允许不可达的代码。

  • undefined(默认):不可达代码会有警告,但不报错
  • true:允许不可达代码,不警告
  • false:不允许不可达代码,报错

比如:

function foo() {
  return 1;
  console.log('hello'); // 不可达代码
}

推荐值false。不可达代码通常是错误,不应该存在。

8. allowUnusedLabels

allowUnusedLabels允许未使用的标签。

和allowUnreachableCode类似,建议设为false,未使用的标签通常是错误。

五、模块解析选项

1. moduleResolution

moduleResolution指定模块解析策略,也就是TypeScript怎么查找import的模块。

可选值:

  • node:Node.js风格的模块解析,按Node.js的规则查找模块(先找node_modules,再找上级目录)
  • classic:经典的模块解析策略,TypeScript早期的方式,现在用得少
  • node16/nodenext:TypeScript 4.7+引入的,支持Node.js的ESM和CommonJS混合解析

推荐值node。大部分项目用Node.js风格的模块解析就行。如果是Node.js ESM项目,可以用node16nodenext

2. baseUrl

baseUrl指定模块解析的基础目录,用来支持非相对路径的导入。

比如设置baseUrl: "./src",那么import foo from 'utils/foo'会从src/utils/foo查找模块,不需要写相对路径../../utils/foo

baseUrl在大型项目中很有用,能避免复杂的相对路径。

3. paths

paths指定模块路径映射,配合baseUrl使用,可以把模块路径映射到具体的文件或目录。

比如:

{
  "baseUrl": "./src",
  "paths": {
    "@/*": ["*"],
    "@components/*": ["components/*"],
    "@utils/*": ["utils/*"]
  }
}

这样就可以用import Button from '@components/Button'来导入,而不用写复杂的相对路径。

注意:paths只是TypeScript编译时的路径映射,运行时(Node.js或浏览器)不认识这些别名,需要配合打包工具(webpack的resolve.alias、Vite的alias等)或运行时工具(tsconfig-paths)来处理。

4. rootDirs

rootDirs指定多个根目录,把多个目录虚拟成一个根目录,允许跨目录的相对导入,就像在同一个目录下一样。

这个选项用得比较少,一般在特殊的项目结构中才用到。

5. typeRoots

typeRoots指定类型声明文件的根目录,TypeScript默认会从node_modules/@types目录加载类型声明。

如果你有自定义的类型声明目录,可以用typeRoots指定。一般项目不需要改这个选项。

6. types

types指定要包含的类型声明包列表,默认会包含typeRoots下的所有包。

如果你只想包含特定的类型声明包,可以用types指定:

"types": ["node", "jest"]

这样就只会包含@types/node和@types/jest,其他@types下的包不会被自动包含。

一般项目不需要配置这个,默认包含所有就行。但在某些情况下(比如测试类型污染了生产代码),可以用types隔离。

六、源码映射和调试选项

1. sourceMap

sourceMap生成source map文件(.js.map),方便调试编译后的JavaScript代码。

开启后,编译时会生成对应的.map文件,浏览器的开发者工具可以通过source map把编译后的代码映射回原始的TypeScript代码,调试的时候能直接在TypeScript源码上打断点。

推荐值:开发环境true,生产环境根据需要决定。生产环境如果不需要调试,可以不生成source map,减小文件体积。但如果需要线上调试,可以生成source map但不发布到公网。

2. inlineSourceMap

inlineSourceMap把source map内联到.js文件中,而不是生成单独的.map文件。

和sourceMap二选一,一般用sourceMap生成单独的.map文件更清晰。inlineSourceMap适合一些特殊场景,比如不想有额外的文件。

3. inlineSources

inlineSources把TypeScript源码内容内联到source map中。

开启后,source map里会包含原始的TypeScript源码,这样即使没有源文件,也能通过source map看到原始代码。一般用于调试场景。

4. declaration

declaration生成类型声明文件(.d.ts)。

如果你在开发一个库(npm包),需要让使用你库的人有类型提示,就需要生成.d.ts声明文件。开启declaration后,编译时会为每个.ts文件生成对应的.d.ts文件。

推荐值:应用项目false,库项目true

5. declarationMap

declarationMap生成类型声明文件的source map(.d.ts.map)。

配合declaration使用,生成.d.ts的source map,方便库的使用者跳转到你的源码。库项目建议开启。

6. outFile

outFile指定输出文件,把所有编译后的代码合并成一个.js文件。

这个选项只在module是AMD或System的时候有效,CommonJS和ES Module不支持合并输出。一般项目用打包工具(webpack、rollup)来做代码合并,不用这个选项。

七、高级配置选项

1. lib

lib指定编译时包含的内置类型库,也就是TypeScript知道哪些JavaScript API存在。

可选值很多,比如:ES5ES6/ES2015ES2016ES2017ES2018ES2019ES2020ESNextDOMDOM.IterableWebWorkerScriptHost等。

  • ES2015+:包含对应版本的JavaScript API的类型声明,比如Promise、Map、Set等
  • DOM:包含浏览器DOM API的类型声明,比如document、window等
  • DOM.Iterable:包含DOM可迭代对象的类型声明

lib的默认值和target有关,target是ES5的话,默认lib是ES5, DOM, ScriptHost;target是ES2015的话,默认lib是ES2015, DOM, ScriptHost

推荐值

  • 浏览器项目:["ES2020", "DOM", "DOM.Iterable"],根据目标浏览器支持的版本调整
  • Node.js项目:["ES2020"],不需要DOM,根据Node.js版本调整
  • 库项目:根据库的运行环境决定

注意:lib只影响类型检查,不影响编译输出。比如你lib里有ES2020,但target是ES5,TypeScript会把ES2020的语法编译成ES5,但需要你自己提供polyfill(比如core-js)。

2. jsx

jsx指定JSX的编译方式,用React等JSX语法的项目需要配置。

可选值:

  • preserve:保留JSX语法,输出.jsx文件,不编译
  • react:编译成React.createElement调用,输出.js文件
  • react-native:保留JSX,但输出.js文件
  • react-jsx:TypeScript 4.1+引入的,使用新的JSX转换,不需要import React

推荐值

  • React 17+项目:react-jsx(需要TypeScript 4.1+),新的JSX转换,不需要手动import React
  • React 16及以下项目:react
  • 其他JSX框架:根据框架要求选择

3. jsxFactory

jsxFactory指定JSX编译时使用的工厂函数,默认是React.createElement

如果你用的不是React,而是其他JSX框架(比如Preact、Vue 3的JSX),可以用jsxFactory指定对应的工厂函数,比如h

4. resolveJsonModule

resolveJsonModule允许导入JSON文件。

开启后,可以用import data from './data.json'导入JSON文件,TypeScript会自动解析JSON的类型。

推荐值true。很多项目都需要导入JSON配置文件,开启后很方便。

5. isolatedModules

isolatedModules确保每个文件都能被安全地单独编译,不依赖其他文件的类型信息。

这个选项在使用转译工具(如Babel、esbuild、swc)的时候需要开启,因为这些工具是逐个文件转译的,不做跨文件的类型分析。开启isolatedModules后,TypeScript会报错那些不能被单独转译的写法,比如:

  • 不能重新导出类型(export { Foo } from './foo',如果Foo是类型会报错,要用export type { Foo }
  • 不能使用const enum(因为const enum需要跨文件分析)
  • 不能有未使用的变量(某些情况下)

推荐值:如果用Babel、esbuild、swc等转译工具,设为true;如果只用tsc编译,可以不设。

6. allowSyntheticDefaultImports

allowSyntheticDefaultImports允许从没有默认导出的模块中默认导入。

这个选项只影响类型检查,不影响编译输出。开启后,可以用import React from 'react'导入CommonJS模块,即使React没有默认导出,TypeScript也不会报错。

注意:这个选项和esModuleInterop不同,esModuleInterop会影响编译输出,生成辅助函数;allowSyntheticDefaultImports只影响类型检查。一般开启esModuleInterop后,allowSyntheticDefaultImports会自动开启。

7. downlevelIteration

downlevelIteration降级迭代,当target是ES5或更低时,正确编译for...of、展开运算符等迭代语法。

不开启的时候,TypeScript会把for...of简单编译成普通的for循环,对于可迭代对象(如Map、Set、Generator)可能不正确。开启downlevelIteration后,TypeScript会生成更正确的迭代辅助代码,但输出文件会更大。

推荐值:如果target是ES5或更低,并且代码中用了for...of、展开运算符、解构等迭代语法,设为true。如果target是ES2015+,不需要这个选项。

8. importHelpers

importHelpers从tslib导入辅助函数,而不是在每个文件中生成辅助函数。

TypeScript编译的时候,会生成一些辅助函数,比如extendsawaiter__generator等。默认情况下,每个用到这些函数的文件都会生成一份,导致重复代码,输出文件变大。

开启importHelpers后,TypeScript会从tslib包导入这些辅助函数,每个辅助函数只有一份,减小输出文件体积。

推荐值:库项目或大型项目true,需要安装tslib依赖(npm install tslib)。小型项目可以不开启,影响不大。

9. experimentalDecorators

experimentalDecorators启用装饰器(Decorator)的实验性支持。

装饰器是ES的提案,还没有正式标准化,TypeScript通过experimentalDecorators选项提供支持。Angular、NestJS、TypeORM等框架大量使用装饰器。

推荐值:如果用了装饰器(Angular、NestJS、TypeORM等),设为true;否则不需要。

10. emitDecoratorMetadata

emitDecoratorMetadata输出装饰器的元数据,配合experimentalDecorators使用。

开启后,TypeScript会在编译后的代码中输出装饰器的元数据信息(比如参数类型、返回值类型),供运行时的反射API使用。NestJS、TypeORM等框架需要这个选项来实现依赖注入、ORM映射等功能。

推荐值:如果用了NestJS、TypeORM等需要运行时类型元数据的框架,设为true;否则不需要。

八、项目引用和monorepo配置

TypeScript 3.0引入了项目引用(Project References),用于大型项目或monorepo的多项目构建。

1. references

references指定要引用的其他TypeScript项目,每个引用是一个包含path的对象,指向另一个tsconfig文件或目录。

比如:

{
  "references": [
    { "path": "./packages/core" },
    { "path": "./packages/utils" }
  ]
}

项目引用允许你把一个大项目拆成多个小项目,每个项目有自己的tsconfig,独立编译,提升编译速度。同时,项目之间可以互相引用,共享类型。

使用项目引用的时候,需要用tsc --build来构建,而不是普通的tsc

2. composite

composite标记项目是否可以被引用,被引用的项目必须开启composite。

开启composite后:

  • 必须设置rootDir(或者TypeScript能自动推断)
  • 必须生成declaration文件(.d.ts)
  • 所有输入文件必须被include或files包含
  • 编译时会生成.tsbuildinfo文件,记录构建信息,用于增量构建

3. incremental

incremental启用增量编译,TypeScript会记录上次编译的信息,下次编译时只编译变化的部分,提升编译速度。

开启后,编译时会生成.tsbuildinfo文件,保存编译状态。

推荐值:大型项目true,能显著提升重新编译的速度。小型项目编译本来就快,可以不开启。

4. tsBuildInfoFile

tsBuildInfoFile指定.tsbuildinfo文件的路径,默认在outDir下。

一般不需要改,用默认路径就行。

九、推荐的tsconfig配置

讲了这么多配置项,最后给几个推荐的tsconfig配置模板,大家可以根据自己的项目类型选择。

1. Node.js应用项目

{
  "compilerOptions": {
    "target": "ES2019",
    "module": "commonjs",
    "lib": ["ES2019"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "declaration": false,
    "sourceMap": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

2. 浏览器应用项目(React + 打包工具)

{
  "compilerOptions": {
    "target": "ES2017",
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "jsx": "react-jsx",
    "moduleResolution": "node",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "sourceMap": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "baseUrl": "./src",
    "paths": {
      "@/*": ["*"]
    }
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

3. 库项目(npm包)

{
  "compilerOptions": {
    "target": "ES5",
    "module": "ESNext",
    "lib": ["ES2015", "DOM"],
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
    "declarationMap": true,
    "sourceMap": true,
    "importHelpers": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist", "**/*.test.ts"]
}

这些模板覆盖了大部分项目场景,大家可以根据自己的具体需求调整。

十、写在最后

TypeScript的配置项很多,但常用的也就那些。理解了每个配置项的作用,就能根据项目需求写出合理的tsconfig配置。

配置tsconfig的核心原则是:

  1. 严格模式要开启:strict: true,这是类型安全的基础
  2. target和module要匹配运行环境:根据目标环境(浏览器/Node.js版本)选择
  3. 输出目录要清晰:指定outDir和rootDir,不要让编译文件和源码混在一起
  4. 常用的严格检查要开启:noUnusedLocals、noUnusedParameters、noImplicitReturns等,能帮你写出更好的代码
  5. 第三方库的问题要规避:skipLibCheck: true,避免第三方库声明文件的问题
  6. 根据项目类型调整:应用项目、库项目、Node.js项目、浏览器项目,配置各有不同

TypeScript 4.0带来了一些新特性,比如可变元组类型、标记的元组元素、构造函数的类属性推断、catch子句的unknown类型等,这些新特性不需要额外配置,升级到4.0就能用。

最后想说,tsconfig不是一成不变的,随着项目的发展和TypeScript版本的升级,配置也需要调整。定期 review 一下tsconfig,看看有没有需要更新的配置,能让你的项目保持最佳的类型检查和编译效果。

希望这篇配置详解能帮你更好地理解和配置TypeScript。如果你有其他配置问题或者更好的实践,欢迎在评论区交流。