tsconfig常用配置全解
作者:互联网
- include, exclude, files配置项
- extends配置
- compilerOptions下的配置
- compilerOptions.allowUnreachableCode
- compilerOptions.allowUnusedLabels
- compilerOptions.alwaysStrict
- compilerOptions.exactOptionalProperties
- compilerOptions.downlevelIteration
- compilerOptions.importHelpers
- compilerOptions.strict
- compilerOptions.strictBindCallApply
- compilerOptions.strictFunctionTypes
- compilerOptions.strictNullChecks
- compilerOptions.strictPropertyInitialization
- compilerOptions.noImplicitAny
- compilerOptions.noImplicitOverride
- compilerOptions.noImplicitReturns
- compilerOptions.noImplicitThis
- compilerOptions.noPropertyAccessFromIndexSignature
- compilerOptions.noUncheckedIndexedAccess
- compilerOptions.noUnusedLocals
- compilerOptions.noUnusedParameters
- compilerOptions.useUnknownInCatchVariables
- 小结
基于typescript的项目的根目录下都会有一个文件(tsconfig.json
), 这个文件主要用来控制typescript编译器(tsc, typescript compiler)的一些行为, 比如指定哪些文件需要让tsc来编译, 哪些文件不想让tsc进行编译之类的.
angular项目的tsconfig.json
文件
tsconfig.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictTemplates": true
}
}
这其中angularCompilerOptions
顾名思义是angular专用的, 不在本文讨论范围.
include, exclude, files配置项
include
: 指定要编译哪些文件, 比如只需要编译<project-dir>/src
目录下的.ts源代码文件
{
"compilerOptions": {
...
},
include: ["./src/**/*", "./demo/**/*.tsx?"]
}
上面的include配置用到了两个通配符: **/
, *
**/
表示匹配任何子路径, 包括目录分隔符/
也会被它匹配, 所以用来这个通配符后, 目录下有多少子目录都会被匹配到
*
表示匹配除了目录分隔符(/
)外的任何长度的字符串
?
表示匹配一个除文件分隔符(/
)外的任一字符
显然./src/**/*
即表示匹配src
文件夹下的任何子文件夹的任何文件; 而./demo/**/*.tsx?
即表示匹配demo
目录下任何子目录下的任意以.ts
或.tsx
结尾的文件
include其实就是一个白名单, 在这个白名单里被匹配到的文件才会被tsc处理编译
相对于include
是作为白名单的配置, exclude
选项就是一个黑名单了, 它的值和include一样是一个路径名字符串数组, 最常见的用处就是用来排除掉node_modules
目录下的文件
{
"compilerOptions": {
...
},
include: ["./src/**/*", "./demo/**/*.tsx?"],
exclude: ["node_modules/**/*"]
}
当然也可以用exclude
排除掉include
里面包含到的文件
有些情况即使exclude了某些文件后, 编译后的代码中可能仍然包含被
exclude
了的内容, 比如通过import
导入了被exclude
了的node_modules
文件夹, 此时tsc仍然会去处理被exclude了的文件, 这一点应该不难理解
files
配置的作用类似include
, 也是一个白名单路径数组, 不同在于它不能使用通配符, 而必须使用精确的文件路径(可以是相对路径), 比如如果项目只有一个入口文件, 那么就可以使用在只用files
配置这个文件的路径, 然后其他的文件都通过index.ts
来import
tsconfig.json
{
"compilerOptions": {
...
},
// include: ["./src/**/*", "./demo/**/*.tsx?"],
// exclude: ["node_modules/**/*"]
files: ['./src/index.ts']
}
extends配置
extends
用于在一个tsconfig.json
文件中扩展其他tsconfig.json
文件, 比如angular项目中有三个tsconfig配置文件: tsconfig.json
, tsconfig.spec.json
, tsconfig.app.json
tsconfig.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
},
...
}
tsconfig.app.json
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"files": [
"src/main.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.d.ts"
]
}
tsconfig.spec.json
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
...
"files": [
"src/test.ts",
"src/polyfills.ts"
],
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
从命名和文件内容上即可看出之所以这么做是为了针对测试文件.spec.ts
和普通.ts
文件在使用不同的配置时又能共享他们相同部分的配置, 达到避免重复的目的
compilerOptions下的配置
compilerOptions.allowUnreachableCode
表示是否允许代码中出现永远无法被执行到的代码, 可选值是undefined
, false
, true
{
"compilerOptions": {
"allowUnreachableCode": false
...
},
...
}
什么是"永远无法被执行到的代码"?
const foo = () => {
return 0;
console.log('aaa'); // 这一行代码就是永远被执行到的代码
}
配置为undefined
时, 遇到这种情况会给出warning, 配置false则直接编译时抛出错误无法成功编译, 配置为true既没有警告也没有错误
compilerOptions.allowUnusedLabels
这个选项是针对标签(label)语法的, 这个语法很罕见, 我也是看到了这个配置才知道有这个原来js还有Label
语法, label语法有点像其他语言里的goto, 真是场景中几乎不用
compilerOptions.allowUnusedLabels
表示是否允许未使用到的标签
可选项:
undefined
: 这是默认值, 碰到未使用的标签给出warning警告false
: 碰到未使用的标签抛出错误, 编译失败true
: 碰到未使用的标签编译通过, 且不给出异常
function bar() {
console.log('loafing...');
loop: for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
if (i === 2) {
// break loop;
}
console.log(i, j, i + j);
}
}
}
compilerOptions.alwaysStrict
默认值是true
, 开启这个选项保证输出的js代码处于ECMAScript标准的严格模式下, 也就是js文件里的use strict
compilerOptions.exactOptionalProperties
这是typescript4.4中才加入的一个选项, 默认处于不开启状态; 开启此选项, typescript会对可空属性执行更严格的类型检查, 可空属性只有在初始化时可以留空为undefined
, 但是不能被手动设置为undefined
例如有一个IFoo
接口
interface IFoo {
foo?: string;
}
在compilerOptions.exactOptionalProperties = false
情况下
const obj: IFoo = {};
obj.foo = '1111';
console.log(obj.foo);
obj.foo = undefined;
console.log(obj.foo);
这段代码可以正常编译通过
但如果开启compilerOptions.exactOptionalProperties
选项后情况就不同了
const obj: IFoo = {};
obj.foo = '1111';
console.log(obj.foo);
// 编译器会报: Type 'undefined' is not assignable to type 'string' with 'exactOptionalPropertyTypes: true'. Consider adding 'undefined' to the type of the target.
obj.foo = undefined;
console.log(obj.foo);
// 这一行会报: Type '{ foo: undefined; }' is not assignable to type 'IFoo' with 'exactOptionalPropertyTypes: true'.
const obj2: IFoo = {
foo: undefined
}
compilerOptions.downlevelIteration
先解释下什么是Downleveling
? Downleveling
是Typescript中的一个术语, 它表示将typescript代码转译为相对更低版本的javascript
这个标志位模式是不开启的.
开启这个标志位typescript会生成一个帮助方法来对es6中的for of
和数组展开([...arr]
)语法进行转译, 以兼容es3/es5
下面的示例用for of
循环并输出一个包含符号表情的字符串:
const text = `(标签:常用,typescript,console,log,text,compilerOptions,全解,foo,tsconfig
来源: https://www.cnblogs.com/laggage/p/explain-some-options-of-tsconfi.html