extends

作用:
指定需要继承的tsconfig.json配置文件,可以是npm包也可以是本地文件

示例:

{
  "extends": "./tsconfig.base.json",
  "extends": "@tsconfig/recommended/tsconfig.json"
}

references

作用:
让一个仓库中的多个关联的子应用能够联动编译

示例:

/mono-repo
  /libs
    /common
      tsconfig.json
  /apps
    /api-service
      tsconfig.json
    /web-app
      tsconfig.json
// libs/common/tsconfig.json
{
  "compilerOptions": {
    "outDir": "../dist/common",
    "composite": true
  },
  "include": ["src/**/*"]
}
// apps/api-service/tsconfig.json
{
  "compilerOptions": {
    "outDir": "../dist/api"
  },
  "references": [
    { "path": "../libs/common" }
  ],
  "include": ["src/**/*"]
}
// apps/web-app/tsconfig.json
{
  "compilerOptions": {
    "outDir": "../dist/frontend"
  },
  "references": [
    { "path": "../libs/common" }
  ],
  "include": ["src/**/*"]
}

frontend和api都依赖了common,通过在references中指定common,当修改了common的代码后,就会触发所有依赖者的重新编译,确保依赖者能够访问到最新的common,适用于mono-repo工程,即一个仓库包含多个子应用,比如一个仓库中有前端代码和后端代码

exclude

作用:
指定不需要编译的文件或者目录

示例:

/project-root
  /src
  /dist
  /node_modules
  /tests
  tsconfig.json
{
  "exclude": [
    "node_modules",  // 排除node_modules目录
    "dist",          // 排除dist目录
    "tests"          // 排除tests目录
  ]
}

include

作用:
指定需要编译的文件或目录

示例:

{
  "include": [
    "src/**/*.ts"  // src目录及其子目录下的所有.ts文件
  ]
}

files

作用:
明确指定需要编译的文件(不能使用模式匹配)

示例:

{
  "files": [
    "src/xx.ts"
  ]
}

场景:
当你明确知道只有少量文件需要编译的时候

compilerOptions

outDir

作用:
指定编译后的文件放到哪里

注意:
当指定的目录不存在时,编译器会自动创建

rootDir

作用:
指定需要编译代码所在的目录

removeComments

作用:
在编译过程中移除注释

默认值:
false

module

作用:
指定要将代码编译为哪种模块系统。

默认值:
取决target的值,如果target是ES3或者ES5,那么module的默认值就是CommonJS,如果target是ES2015、ES2016 等等,module的默认值就是ES Modules

场景:
如果你的项目是Nodejs项目,在代码中使用了import语法,而Nodejs是不支持import(ES6)语法的,Nodejs支持的是CommonJS语法。
这时我们就可以通过module告诉ts编译器,将代码转换为CommonJS语法,这样就能在Nodejs中运行了。

当module为ES6
image.png
当module为CommonJS
image.png

outFile

作用:
将所有源码编译合成为一个js文件,前提是module选项被设置成System或者AMD

示例:
没有使用outFile
image.png
使用outFile

{
  "outFile": "./dist/bundle.js",
}

image.png

注意:
outFile的输出目录不会基于outDir的值,所以你需要在outFile中指定目录

sourceMap

作用:
生成源代码与编译后代码之间的映射关系,映射关系会存在.map文件中以便于调试(主流浏览器的调试工具都支持sourceMap功能,会按照默认的规则找到.map文件,然后解读源代码和编译后代码之间的隐射关系)

inlineSourceMap

作用:
和sourceMap的作用一样,区别是不会额外生成.map文件,而是将.map文件的内容合并的编译后的文件中

declaration

作用:
生成.d.ts声明文件

示例:
image.png

默认值:
false

注意:
只有导出的部分才会被生成为.d.ts文件
在下面的代码中,只有导出的add才会生成类型定义

const name: string = 'tomcat'
export const add = (a: number, b: number):number => a + b;

建议:
如果你是开发npm包的建议开启,如果是业务项目开发,则无需开启

declarationDir

作用:
将declaration开启后声明的.d.ts文件统一放到指定目录中

示例:
指定前
image.png

指定后

{
  "declarationDir": "./dist/types"
}

image.png

lib

作用:
当你指定target的时候,ts会偷偷引入一些.d.ts类型声明文件,如果你想额外引入一些默认引入没有包含的声明文件,则可以通过lib来实现

注意:
一旦你使用了lib属性,那么target默认引入的声明文件将被取消,所以一旦你使用了lib属性,你就需要把target默认引入的库文件显示的引入一遍,否则就会导致默认的声明文件丢失,导致编译失败

typeRoots

作用:
指定类型文件所在的目录

使用场景:
默认的,typesript只会从node_modules/@types和当前当tsconfig.json所在目录的根目录和子孙目录中查找类型文件,当你的类型文件不在这些位置时,就需要通过typeRoots来指定了,比如在mono-repo项目中,你的类型文件可能在当前package的上层,这时typescript无法自动读取到你需要的声明文件。

示例:
目录结构如下

/my-large-project
  /shared
    /types
      custom-types.d.ts
  /sub-project-1
    tsconfig.json
    ...
  /sub-project-2
    tsconfig.json
    ...

在sub-project1或者2中通过typeRoots引入shared中的类型声明文件

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es6",
    "typeRoots": ["../shared/types"]
  },
  "include": [
    "**/*.ts"
  ]
}

注意:
typeRoots是一个复写操作,而不是增量操作。也就是当你显示的声明typeRoots后,ts就不会再使用node_modules/@types中的声明了,文档虽然是这样说的,但我发现,即时你将typeRoots修改为了非node_modules/@types,比如置空,typescript还是回去从node_modules/@types中找类型声明,可能是其他的机制?先搁置

types

作用:
告诉typescript只从node_modules/types中读取指定的类型文件

示例:
默认情况下,typescript会将node_modules/@types中的所有包类型文件声明至全局空间

node_modules/@types/node
node_modules/@types/express
node_modules/@types/lodash

通过设置types属性,我们可以让typescript仅将node_modules/@types/express中的类型定义声明至全局空间

{
  "compilerOptions": {
    "types": ["express"]
  }
}

allowJs

作用:
允许在代码中导入.js文件

场景:
在ts文件中,如果你import一个js文件,但是没有设置allowJs为true,首先编译器会报错,然后,即使你将错误检查关掉,在编译结果中,也不会包含你Import的js文件

checkJs

作用:
让ts对js文件进行类型检查

示例:
开启前
image.png
开启后
image.png

useDefineForClassFields

作用:
告诉typescript如何编译class

示例:

class MyClass {
  public field = 'value';
}

当useDefineForClassFields为false,会被typescript编译为

class MyClass {
  constructor() {
    this.field = 'value';
  }
}

当useDefineForClassFields为true,会被typescript编译为

class MyClass {
  constructor() {
    Object.defineProperty(this, 'field', {
      enumerable: true,
      configurable: true,
      writable: true,
      value: 'value'
    });
  }
}

默认值:
如果 target 编译器选项设置为 ES2022 或更高版本,包括 ESNext,则 useDefineForClassFields 的默认值为 true。
如果 target 设置为 ES2022 以下的版本,则默认值为 false

skipLibCheck

作用:
跳过ts类型检查

moduleResolution

作用:
优化编译性能

allowImportingTsExtensions

作用:
让我们可以在引入ts文件时,加上.ts文件后缀(啊?默认情况下引入.ts文件不能写后缀吗?还需要开启这个属性才能写文件后缀?我竟然不知道)

示例:
allowImportingTsExtensions为false

// 会报错
import utils from './utils.ts'

allowImportingTsExtensions为true

// 不会报错
import utils from './utils.ts'

resolveJsonModule

作用:
允许在ts中直接引入.json文件

示例:
resolveJsonModule:false

// 会报错
import data from './data.json'

resolveJsonModule:true

// 不会报错
import data from './data.json'

注意:
如果你的moduleResolution为bundler,那么会包含resolveJsonModule为true的效果

isolatedModules

作用:
告诉typescript对每个文件进行独立编译,以提高编译速度

注意:
启用这个属性之后,会禁用一些需要跨文件推断类型的特性
1 不能使用const enum
2 每个文件都必须包含import或者export(二者其一)
3 不能使用全局模块扩充
4 不能使用/// <reference />

建议:
一般情况下不需要开启

noEmit

作用:
让ts不要进行文件编译,只进行类型检查

场景:
当你使用了构建工具进行了ts编译的时候,可以将这个开启,将编译工作交给构建工具

jsx

作用:
告诉ts如何处理jsx语法

默认值:
preserve
告诉ts遇到jsx不做额外处理

建议:
一般情况不需要设置该属性,使它保持默认值preserve

strict

作用:
告诉ts进行严格的类型检查
当 "strict": true 时,以下选项会被自动启用:
● noImplicitAny: 禁止隐式的 any 类型。
● strictNullChecks: 更严格的空值检查。
● strictFunctionTypes: 对函数参数进行更严格的检查。
● strictBindCallApply: 对 bind、call 和 apply 方法的参数进行更严格的检查。
● strictPropertyInitialization: 确保类的非空属性在构造函数里被初始化。
● noImplicitThis: 当 this 表达式的值为 any 类型时,生成一个错误。
● alwaysStrict: 以严格模式解析并为每个源文件生成 "use strict" 语句。

noUnusedLocals

作用:
让ts检查那些声明了但是却没有使用的局部变量

示例:

function example(x: number, y: number) {
 let z = 10; // 报错:'z' 被声明但从未使用
 return x + y;
}

noUnusedParameters

作用:
让ts检查函数中定义了,但却未使用的参数

示例:

function example(x: number, y: number) { // 错误:'y' 被声明但从未使用
 return x * 2;
}

noFallthroughCasesInSwitch

作用:
让ts在遇到switch贯穿问题时进行报错,防止意外的疏忽

示例:

function example(value: number) {
 switch (value) {
   case 1:
     console.log("One");
     // 错误:这里会报告贯穿错误,因为没有 break 或 return
   case 2:
     console.log("Two");
     break;
 }
}

建议:
如果确定项目中不会使用switch语句,那就没必要开启了

esModuleInterop

作用:
简化导入CommonJS的语法

示例1:
esModuleInterop: false

const path = require('path')

esModuleInterop: true

import path from 'path'

示例2:
esModuleInterop: false

import * as express from 'express';
const app = express();

esModuleInterop: true

import express from 'express';
const app = express();

forceConsistentCasingInFileNames

作用:
强制要求文件的大小写一致

示例:
forceConsistentCasingInFileNames: false

import { someFunction } from './Utils.ts';
import { anotherFunction } from './utils.ts';
// 两者都会被接受,即使实际文件名是 "Utils.ts"

forceConsistentCasingInFileNames: true

// 假设实际文件名是 "Utils.ts"
import { someFunction } from './utils'; // 错误:文件名大小写不匹配

默认值:
true

建议:
始终保持开启状态

资料

https://pengfeixc.com/blogs/javascript/tsconfig
https://www.typescriptlang.org/tsconfig


热饭班长
3.7k 声望434 粉丝

先去做,做出一坨狗屎,再改进。