承接上一篇内容,typescript语法传送门:juejin.cn/post/741591…
在 TypeScript 项目的根目录下执行 tsc-init 命令,创建一个 tsconfig.json 文件。用于配置 TypeScript 编译项目时编译器所需的选项。
1 基础配置
{
"compilerOptions": {
"target": "es2016", // 编译生成的目标版本代码
// "lib": ["esnext","dom","dom.iterable","scripthost"], // 指定我们需要用到的库,也可以不配置,直接根据 target 来获取 /* Specify a set of bundled library declaration files that describe the target runtime environment. */
"jsx": "preserve", // jsx 的处理方式(保留原有的jsx格式)
"module": "ESNext", // 生成代码使用的模块化
"moduleResolution": "Bundler", // 支持各种打包工具,路径查询解析
"baseUrl": "./", // 文件路径在解析时的基本url
// "paths": {"@/*":["src/*"]}, // 路径的映射设置,类似于webpack中的 alias
// "types": ["webpack-dev"], // 指定需要加载哪些 types 文件(默认都会进行加载)
"allowJs": true, // 允许在项目中导入 JavaScript 文件
"sourceMap": true, // 是否要生成 sourcemap 文件
"importHelpers": true, // 是否帮助导入一些需要的功能模块
"allowSyntheticDefaultImports": true, // 允许合成默认模块导出
"esModuleInterop": true, // 支持es module 和 commonjs 混合使用
"strict": true, // 打开所有的严格模式检查
"noImplicitAny": false, // 为具有隐含“any”类型的表达式和声明启用错误报告
"skipLibCheck": true, // 跳过对整个库的类型检测,而仅检测你用到的类型
"include": [ // 指定编译时包含的文件
"src/**/*.ts",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude":["node_modules"] // 指定编译时应跳过的文件
}
}
| 描述 | 基础使用 |
|---|---|
| 根字段 files:包含在程序中的文件的允许列表。如果找不到任何文件,则会发生错误 | {compilerOptions:{}, files:["a.ts","c.ts"]} |
| 根字段 include:包含在程序中的文件名或模式数组。 这些文件名相对于包含文件的目录进行解析 | {compilerOptions:{}, include:["src//*.ts","tests//*"]} |
| 根字段 exclude:解析 include 时应跳过的文件名或模式数组 | {compilerOptions:{}, exclude:["tests/**/*"]} |
| references: 用于支持项目引用(Project References),将大型 TypeScript 项目分解为多个较小的、更易于管理的子项目(或称为“项目”) | {compilerOptions:{}, references:[{ "path": "../project1" },{ "path": "../project2" }, ...]} |
| CompilerOptions:编辑器选项 | 选项构成了 TypeScript 配置的大部分内容,它涵盖了该语言的工作方式 |
2 CompilerOptions配置=>类型检查
| 描述 | 基础使用 |
|---|---|
| allowUnreachableCode:允许无法访问的代码 (undefined, true, false) | |
| allowUnusedLabels:允许未使用的标签(undefined, true, false) | |
| alwaysStrict:始终严格 | 确保在 ECMAScript 严格模式下解析文件,并为每个源文件发出“use strict” |
| exactOptionalPropertyTypes:确切的可选属性类型 | |
| noFallthroughCasesInSwitch:Switch 中没有 Fallthrough Case 控制 TypeScript 编译器是否应该报错,当在 switch 语句中遇到一个 case 分支而没有使用 break、return、throw 或者下一个 case 分支的进入时(这通常被称为“case 穿透”或“case 跌落”) | |
| noImplicitAny:没有隐式any | |
| noImplicitOverride(No Implicit Override): 当类中的方法被标记为override时,TypeScript 编译器会检查该方法是否确实在基类中有一个同名方法。如果没有,编译器会报错 | true: 如果同名,需要override, false则不显示错误 |
| noImplicitReturns(No Implicit Returns): 启用后,TypeScript 将检查函数中的所有代码路径,以确保它们返回值 | |
| noImplicitThis(No Implicit This) 启用后,在具有隐含“any”类型的“this”表达式上引发错误。也就是说当“this”的类型为“any”时启用错误报告 | |
| noPropertyAccessFromIndexSignature(不能直接从索引签名中访问属性) | noPropertyAccessFromIndexSignature: true: |
| noUncheckedIndexedAccess: 禁止未经检查的索引访问 开启后,当使用索引访问时,将“undefined”添加到类型中 | noUncheckedIndexedAccess:true |
| noUnusedLocals(没有未使用的局部变量): 报告未使用的局部变量的错误 | noUnusedLocals: true |
| noUnusedParameters(没有未使用的参数): 当设置为true时,报告函数中未使用的参数的错误 | noUnusedParameters:true |
| strict: true | 严格模式,支持广泛的类型检查行为,从而更强地保证程序的正确性。启用此功能等同于启用所有严格模式系列选项。然后,您可以根据需要关闭单个严格模式系列检查 |
| strictBindCallApply(Strict Bind Call Apply): 为了确保在使用 bind、call 和 apply 方法时,参数的类型是正确的 属于 strict 选项组的一部分。当你设置 strict 为 true 时,strictBindCallApply 也会默认启用,除非你明确地将它设置为 false | |
| strictFunctionTypes(严格的函数类型): 启用后,此标志会更正确地检查函数参数。只有当一个函数的参数类型是另一个函数参数类型的子集时,才允许进行赋值。这有助于提高代码的类型安全性 strictFunctionTypes 选项并不直接处理类或对象字面量的方法类型。它主要影响的是函数类型之间的兼容性 | |
| strictNullChecks(严格的 Null 检查) | |
| strictPropertyInitialization严格的属性初始化),默认为true | |
| useUnknownInCatchVariables(在 Catch 变量中使用未知): 允许将 catch 子句中的变量类型声明为 unknown |
3 CompilerOptions配置=> typescript模块理论
typescript支持多种模块,这里中点学习ECMAScript(EMS)和 CommonJS(CJS)两种。
- ECMAScript
// a.js
export default 'hello from a.js';
// b.js
import a from 'a.js';
- Commonjs
// a.js
exports.message = 'hello from a.js';
// b.js
const a = require('a.js');
console.log(a.message);
TS编译器针对目标环境编译代码,提供3个选项:
- target - 生成的代码的JS语言的版本,比如ES3、ES5、ES2015等
- module - 模块系统,生成的代码所需要支持的模块系统,比如es2015、commonsjs、systemjs等
- lib - 库,告诉TS目标环境中有哪些特性,比如 ES5、ES2015、DOM等。TS并不实现这些特性,TS预期JS代码运行环境,要么原生环境、要么通过polyfill提供支持。
3.1 模块输出格式(module)
编译器module选项提供该信息,控制编译过程中生成的任何javascript模块格式,也用于通知编译器应该如何检测每个文件生成的模块类型(例如是否有import这样的特性、是否可以使用 import.meta,top-level await等)。
| 描述 | 基础使用 |
|---|---|
| node16 | 反映 Node.js v16+ 的模块系统,同时支持 ES 模块和 CJS 模块以及特定的互操作性和检测规则 |
| nodenext | 反映最新的 Node.js 版本 |
| es2015 | JavaScript 模块的 ES2015 语言规范, 首次引入该export语言的版本 |
| es2020 | 增加了对import.meta和export * as ns from "mod" |
| es2022 | 增加 top-level await 的支持 |
| esnext | 反映最新的 ECMAScript 规范 |
| commonjs, system, amd, and umd | 不推荐用于新项目 |
模块格式检测
nodejs有ES模块和CJS模块,文件的格式由文件拓展名和package.json的type字段决定。
.mjs和.cjs文件被解析为es模块和cjs模块- 如果
package.json中包含了字段type:module,.js被解析为es模块。如果没有包含则.js文件就爱那个解析为cjs模块
3.2 解析模块规则(moduleResolution)
moduleResolution: 按照什么样的规则找到模块,将模块信息提供给你,让你在编写代码的时候,可以看到类型提示。
tsc遇到import语句,不会导入jsor ts代码,它只负责将ts文件编译为js文件,例如import 'a.js'转为require('a.js'), tsc不会改变导入路径,这是bundle工具做的事,bundle工具会识别require,根据自己的搜索方式,加载被导入的moudle,规则依据就是moduleResolution。
| 描述 | 基础使用 |
|---|---|
| classic(将于Typscript6.0移除) | 当moudle为commonjs 或者node16时,默认为classic。新项目不应使用它 |
| node10(以前称为node) | module必须设置commonjs,因为nodeV12之前不支持esmodule风格代码,如果不配置commonjs,编写和编译都不会报错,但是node执行代码时报错。新版node.js,不应使用它 |
| node16 | 对应module=node16,tsc按照新版本 node 的方式寻找模块, 支持esmodule和commonjs, tsc 会识别 package.json 中的 exports 字段,如果这个包不在 node_modules 里,那么 exports字段不会被识别的 |
| nodenext | 对应moudle=nodenext,将支持新的Node.js模块解析特性 |
| bundler(typescript5.0引入) | moudle需设置为esnext,当使用现代打包工具,如 Vite、esbuild、swc、Webpack、Parcel 或其他实现混合查找策略的打包工具,那么新的 bundler 选项应该非常适合。 |
3.3 moudle与moudleResolution 搭配
|描述 |基础使用|
| 描述 | 基础使用 |
|---|---|
| commonJS 风格的 nodejs 程序,不支持解析exports字段,旧版node | {module: "CommonJS",moduleResolution: "Node"} |
| commonJS 风格的 nodejs 程序,支持exports字段 | {module: "CommonJS" |"NodeNext",moduleResolution: "NodeNext"} |
| esModule 风格的 nodejs 程序(需设置 package.json 的 type: "module") | {module: "ESNext" | "NodeNext",moduleResolution: "NodeNext"} |
| 编写浏览器端的代码 | {module: "ESNext", moduleResolution: "Bundler"} |
3.4 path注意
一般会使用 tsconfig.json 的 paths 配置项,简化路径。编写代码时,vscode会解析path,找到对应模块把模块信息提供给你,我们就能得到智能提升,但是编译的时候,这些路径不会被转化为真实的路径,需要通过bundler工具实现真正的路径转化(例如webpack的resolve的alias,vite.config.json 的path)。
3.5 target
TS编译自带的transpiler支持将最新的JS语法特性转换为旧版本的JS语法。您可以在TS中直接使用诸如 async/await, 箭头函数 =>, generator*等。
- 改变 target 同时也会影响到默认的 lib 值。你可以根据需要自由“混合搭配”target 和 lib 的设定,但为了方便,通常只需设置 target 即可自动匹配相应的 lib 配置。
- 特殊的值 ESNext 指代你当前使用的 TypeScript 版本所支持的最高 ES 版本。使用这个设置需谨慎,因为在不同的 TypeScript 版本间它所代表的含义可能不同,可能会使升级过程变得不可预测
| 描述 | 基础使用 |
|---|---|
| ES5(默认值) | 生成的 JavaScript 代码可以在所有现代浏览器中运行,如果你的项目需要支持旧版本的浏览器,可以选择这个 target |
| ES6(生成的 JavaScript 代码兼容 ES6) | 可以在大多数现代浏览器中运行,如果你的项目不需要支持旧版本的浏览器,可以选择这个 target |
| ES2023( 生成的 JavaScript 代码兼容 ES2023) | 可以在最新的浏览器中运行,如果你的项目需要使用一些较新的 JavaScript 特性,可以选择这个 target |
| ESNext(生成的 JavaScript 代码兼容最新的 JavaScript 规范) | 以在最新的浏览器中运行,如果你的项目需要使用一些实验性的 JavaScript 特性,可以选择这个 target |
3.6 lib
TS不会根据目标环境所缺失的功能特性,自动提供polyfill。如果您的目标环境需要某项最新特征,您需要告诉TS编译器,编译器会引入编译所需要的类型定义文件。
| 描述 | 基础使用 |
|---|---|
| ES5 | 包含所有ES3和ES5功能的核心定义。 |
| ES2015(也称为ES6) | 额外的API,如 Array.find, Promise, Proxy, Symbol, Map, Set, Reflect 等。 |
| ES6 | 是 "ES2015" 的别名。 |
| ES2016 | 新增 Array.includes 等API。 |
| ES7 | 是 "ES2016" 的别名。 |
| ES2017 | 引入了 Object.entries, Object.values, Atomics, SharedArrayBuffer, Date.prototype.formatToParts 等API。 |
| ES2018 | 新增迭代器、Promise.prototype.finally, Intl.PluralRules, RegExp.prototype.groups 等API。 |
| ES2019 | 引入了 Array.prototype.flat, Array.prototype.flatMap, Object.fromEntries, String.prototype.trimStart, String.prototype.trimEnd 等API。 |
| ES2020 | 增加了 String.prototype.matchAll 等API。 |
| ES2021 | 引入了 Promise.any, String.prototype.replaceAll 等API。 |
| ES2022 | 新增 Array.prototype.at, RegExp.prototype.hasIndices 等API。 |
| ESNext | 随JavaScript规范演进而变化的额外API。 |
| DOM | 包含 window, document 等DOM相关定义。 |
| WebWorker | Web Worker上下文可用的API。 |
| ScriptHost | Windows脚本宿主系统API。 |
// 假如您的代码跑在浏览器上,使用ES2015,Array的include,您需要设置tsconfig.json的lib参数为:
{
"compilerOptions": {
"lib": ["es2015", "es2016.array.include", "dom"]
}
}
// 假设你正在开发一个Node.js应用,不涉及任何浏览器API,你可能希望在 tsconfig.json 中排除 "dom" 库,同时确保包含了你的Node.js版本支持的ES特性库:
// 指定了目标为 es2017,并包含了 ES2017 标准库、ES2018.Promise(因为即使在ES2017目标下,我们仍可能想使用Promise的最新API),以及 ScriptHost 来支持Node.js环境
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"lib": ["ES2017", "ES2018.Promise", "ScriptHost"]
}
}
3.7 Other
| 描述 | 基础使用 |
|---|---|
| allowArbitraryExtensions(允许任意扩展):默认false | 当设置true,TypeScript编译器将不再限制只导入具有已知文件扩展名(如.ts、.tsx、.js、.jsx等)的文件。这意味着你可以导入具有其他扩展名的文件,只要这些文件有对应的声明文件,TypeScript编译器就能理解这些文件的结构和类型 |
| allowImportingTsExtensions(允许导入 TS 扩展) | 允许TypeScript文件以.ts、.mts或.tsx等TypeScript特有的扩展名相互导入,要求设置“--moduleSolution bundler”和“--noEmit”或“--emitDeclarationOnly” |
| allowUmdGlobalAccess(允许 Umd 全局访问) | 当设置为true,允许在TypeScript模块中通过全局变量的方式访问UMD(Universal Module Definition)模块。 UMD模块定义是一个兼容AMD(Asynchronous Module Definition)和CommonJS的模块定义,它能在多种模块加载器(如RequireJS、AMD、Node.js等)下工作 在你需要访问某些全局库或框架(如jQuery、Underscore等)时非常有用,因为这些库或框架可能会以UMD模块的形式发布,并在全局作用域下暴露一些变量或函数 从 TypeScript 4.1 开始,使用路径时不再需要设置 |
| customConditions:为 TypeScript 的模块解析添加额外的条件 作用:当 TypeScript 解析 package.json 中的 exports 或 imports 字段时,它会考虑 customConditions 中列出的额外条件。这些条件会被添加到解析器默认使用的任何现有条件中 | |
| moduleSuffixes(模块后缀):提供一种在解析模块时覆盖要搜索的文件名后缀的默认列表的方法 | |
| noResolve | 默认情况:编译器在编译之前解析模块并导入,每当成功解析对一个文件的import,则文件将被加入到文件列表中,以便编译器稍后处理。 如果 noResolve 被启用,你需要自己处理这些模块的解析和包含工作,可能是通过其他构建工具或配置来完成 |
| resolveJsonModule(解析 JSON 模块):TS 默认不支持json解析 | |
| resolvePackageJsonExports: 强制TypeScript在读取node_modules中的包时查阅package.json文件的exports字段 当moduleResolution设置为Node16,NodeNext,Bundler时, 该选项的默认值自动设置为true。 | |
| resolvePackageJsonImports: 当从一个文件导入以 #开头的value或者type时, 如果这个文件所在的目录(或者祖先目录)内有一个package.json文件, 开启这个选项会强制 ts 从package.json imports字段确认导入的实际文件 当moduleResolution设置为Node16,NodeNext,Bundler时, 该选项的默认值自动设置为true | |
| baseUrl | |
| rootDir:指定项目的根目录,TypeScript 编译器在寻找输入文件时会从这个目录开始查找 | |
| rootDirs:指定虚拟目录。 告知编译器,有多个 虚拟项目充当单个根目录,这允许编译器解析这些虚拟目录中的相对模块导入,就像将他们合并到一个目录中一样 | |
| typeRoots(类型声明查找目录) 配置项用于指定 TypeScript 编译器在解析类型定义文件(.d.ts 文件)时应该查找的目录 默认情况下,所有可见的“@types”包都包含在编译中。node_modules/@types中的包被认为是可见的,如果指定了typeroot,则只包含typeroot下的包 即使不显式设置 typeRoots,TypeScript 编译器也能够自动查找项目中的 .d.ts 类型声明文件 | |
| types: 默认情况:@types 包都会被包含在你的编译中,包含任何父级目录下的 node_modules/@types.. 如果指定 types字段,则只有在这个列表中列出的包才会被包含在全局作用域中 |
4 CompilerOptions配置 => Emit
4.1 声明文件(.d.ts)
| 描述 | 基础使用 |
|---|---|
| declaration:是否为项目中的TS或者JS文件生成相应的声明文件(.d.ts),当其他的TS引入时可以更好地理解模块类型 - 指定了 outDir:可以指定生成的声明文件和(如果启用)JavaScript 文件的输出目录 | |
| emitDeclarationOnly:和declaration 一起使用,只生成声明文件(.d.ts),不会生成JavaScript文件 | |
| declarationDir: 声明文件(.d.ts)输出目录 | |
| declarationMap:指示 TypeScript 编译器是否为生成的 .d.ts 声明文件生成源映射(source map) |
4.2 源映射文件
| 描述 | 基础使用 |
|---|---|
| inlineSourceMap:true 不会生成sorucemap 文件,而是将 source map 的内容以Base64 编码的形式嵌入到生成的JavaScript文件的末尾。这通过在文件的末尾添加一个特殊的注释(如//#sourceMappingURL=data:application/json;base64,...)来实现,其中... 是 Base64 编码的 source map 内容。 - 嵌入文件尾部,会导致文件过大,需要权衡 - 与sourceMap配置互斥,同时配置为true,优先inlineSourceMap | - 解码base64内容: |
| inlineSources:true,TypeScript 会在 source map 中包含一个嵌入式字符串,该字符串是文件的原始内容 - inlineSources 只有在 sourceMap 或 inlineSourceMap 也被设置的情况下才有效 | |
| mapRoot:true,指定调试器在查找 TypeScript 生成的源映射文件(.map 文件)时应该使用的根路径。 - 开发中,TS编译器将代码编译为JS,并生成源映射文件用于支持调试,默认源文件映射与编译后的js在同一目录,当你希望源映射文件存储在不同位置(例如使用CDN来提供源映射文件),可使用mapRoot指定。 - 需与source map一起使用 | |
| sourceMap(源代码映射文件):是否要生成 sourcemap 文件(一个 .js.map 文件),该文件包含了将生成的 JavaScript 代码映射回原始 TypeScript 代码的信息。这允许开发者在浏览器中调试 TypeScript 代码,即使浏览器实际执行的是 JavaScript | |
| sourceRoot(源文件根路径):指定调试器应查找 TypeScript 文件的位置,而不是相对源位置 | |
| stripInternal:true, TypeScript 编译器在生成 .d.ts 声明文件时不会包含这些带有 @internal 标记的声明 |
4.3 文件生成相关配置
| 描述 | 基础使用 |
|---|---|
| noEmit(无输出文件):true,不输出任何文件,包括(.d.ts)和js源文件,source-maps等文件 | 只想进行 TypeScript 代码的类型检查,而不需要实际编译生成 JavaScript 文件,可通过该配置加速检查 在编辑器中进行类型检查,例如Visual Studio Code在保存TS文件时进行实时检查 |
| noEmitHelpers:默认情况TS编译到不支持目标环境(例如ES5),会引入辅助函数模拟这些特性,这些函数将被导入到文件中。当你想避免辅助函数的导入,只希望它们作为全局函数提供,减少代码生成量,可使用该配置设置为true,那么TS编译器将不会辅助函数导入语句,而是假设这些辅助函数已经在全局存在,意味着你在运行时需要提供这些函数的实现。 - 与其他工具集成时(例如Babel),因为Babel也处理了Typscript的辅助函数,那么当设置noEmitHelpers将会与其产生冲突,根据你的构建工具和配置来调整noEmitHelpers 的设置 | |
importHelpers(导入助手):在某些降级操作中,需要额外的辅助代码来帮助完成,例如拓展数组,拓展对象等,默认情况下辅助类将插入到使用的文件中,在不同模块插入相同代码,将会导致代码重复,可使用改配置,将辅助函数从tslib模块导入。 - 先安装 tslib: npm install tslib --save | |
| noEmitOnError:true,编译器报告错误不输出文件 | 只要编译过程中出现错误,任何文件类型都不要输出 |
| outDir: './dist' | 指定TypeScript编译器编译后的输出目录 |
| outFile:将所有的全局(非模块)TypeScript 文件合并到一个单一的输出文件中,当与某些模块系统(如AMD)一起使用时,它还可以将模块文件合并到这个输出文件中。 - 不能和Commonjs 和ES6一起使用,因为这两者使用了动态导入导出,不适合静态合并 - 只能与module配置为 None \ System \AMD时使用 |
4.4 other
| 描述 | 基础使用 |
|---|---|
| downlevelIteration(降级迭代):现代浏览器支持了新的迭代(for..of,[...arr]等),该编译选项可将现代浏览器支持的迭代特性编译到旧版的JavaScript(特别是ES5) | |
emitBOM:为编译的文件头顶添加Unicode字节顺序标记,对于 UTF-8 编码非常有用。它并不改变文件的实际内容,但可以帮助某些文本编辑器或处理程序正确识别文件的编码。但是在一些旧软件或特定格式文件中,可能BOM会被错误显示处理。- BOM 是一个不可见的特殊字符,对于 UTF-8 编码的文件,BOM 是 EF BB BF 这三个字节 - vscode查看当前编译的文件编码格式(UTF-8 with BOM) | |
| newLine: 'CRLF' 或者 newLine: 'LF', 配置项用于指定在输出文件(例如编译后的 .js 文件)时所使用的行尾序列,在跨平台开发时比较重要。 | - CRLF: Windows 和 DOS 系统使用的行尾字符序列。每个新行都以回车符(\r)后跟换行符(\n)来表示 - LF: Unix 和 Unix-like 系统(如 Linux 和 macOS)使用的行尾字符。每个新行都以换行符(\n)来表示 - 在eslint中检查换行符的配置规则:linebreak-style: unix 或 windows,强制开发使用 unix \n或window \r\n换行符 |
preserveConstEnums(保留枚举声明):默认情况下,枚举会在编译时被完全内联,避免运行时产生额外的枚举对。当设置为true,TS编译器将保留enum的声明,不会将其内联为值,这运行我们在运行时任然可以访问枚举名称。 | |
| removeComments(删除注释) |
5 CompilerOptions配置=>JavaScript Support
| 描述 | 基础使用 |
|---|---|
| allowJs:true, 允许在Typescript项目中引入JavaScript文件 - 只是允许编译器识别 .js文件的ES6模块语法,不会检查.js文件中的类型错误 | |
| checkJs:true, Typescript编译器会检查JavaScript文件中的类型报错. 与allowJS:true配合使用,相当于给项目中的JavaScript文件顶部自动添加了 TypeScript 的类型检查注释 // @ts-check | |
| maxNodeModuleJsDepth: 指定在 node_modules 目录下搜索并加载 JavaScript 文件的最大依赖深度 -仅在启用 allowJs 时可用 - 默认应该为0,如果要设置为大于0,那么需要牺牲速度与潜在准确性为代价 |
6 CompilerOptions配置=>Interop Constraints(操作约束)
| 描述 | 基础使用 |
|---|---|
| allowSyntheticDefaultImports:true 模块 没有默认导出时,转译器可能会自动为模块添加一个默认导出 像这样导入:import React from "react"; 而不是:import * as React from "react"; | |
| esModuleInterop:true,支持es module和commonjs混用,支持使用import d from 'cjs'的方式引入commonjs包。默认false 默认情况下,typescript将 CommonJS/AMD/UMD 模块 视为ES6模块。 有两个部分特别被证明是有缺陷的假设: 缺陷一: import * as moment from "moment" 被视为等同 const moment = require("moment") => 导致问题:ES6模块规范规定命名空间 import * as x 只能是对象,但是由于 TypeScript 将其视为与 require 相同的处理,TypeScript 允许将导入作为函数来调用,这是不符合规范的。=> 解决办法:通过改变编译器的行为来解决的(启用esModuleInterop:true), 启用 esModuleInterop 后,TypeScript 不会强制将命名空间导入视为对象 缺陷二: import moment from "moment" 被视为等同 const moment = require("moment").default => 导致问题:虽然符合 ES6 模块规范,但大多数带有 CommonJS/AMD/UMD 模块的库并不像 TypeScript 的实现那样严格遵循。 => 解决办法:提供了一个 shim 来确保生成的 JavaScript 的兼容性(启用esModuleInterop:true),TypeScript 会尝试从 CommonJS/AMD/UMD 模块中查找 .default 属性(如果存在)。 但是,由于许多库并没有导出 .default,TypeScript 会使用一个 shim 来确保你可以像使用 ES6 模块一样使用默认导入。 | |
| forceConsistentCasingInFileNames(区分文件名大小写), | 确保 TypeScript 在编译时使用的文件名大小写与磁盘上的实际文件名大小写保持一致。这个选项在跨平台开发时特别有用,因为不同的操作系统对文件名的大小写敏感性有不同的处理方式 |
| isolatedModules:true(隔离模块),告诉 TypeScript编译器在编译时考虑单文件编译的限制,因为不是所有的 TypeScript功能都能在单文件编译环境中正确工作 不改变代码行为与输出,只是增加额外的检查确保单文件编译环境的兼容性 | |
| preserveSymlinks:true(保留符号链接) | 是否不解析符号链接的真实路径,这是为了在 Node.js 中反映相同的标志,默认:false。启用此功能后,对模块和包的引用(例如imports和/// 指令)都是相对于符号链接文件的位置解析的,而不是相对于符号链接解析到的路径。 |
| verbatimModuleSyntax: true,告诉TypeScript 编译器不要进行导入省略,而是保留所有的 import 和 export 语句。当设置为 true 时,TypeScript 将会原样输出模块语法,不进行任何省略。 |
7 CompilerOptions配置=>Language and Environment(语言环境)
| 描述 | 基础使用 |
|---|---|
| emitDecoratorMetadata:true,为与模块reflect-metadata一起工作的装饰器发射类型元数据启用实验性支持 | |
| experimentalDecorators:true,启用对decorator的实验性支持 | 参考上面的例子,装饰器是一种语言特性,它还没有被完全纳入JavaScript规范。这意味着当TC39决定时,TypeScript中的实现版本可能与JavaScript中的实现版本不同。 |
jsx:支队.tsx文件有影响,在typescript文件中使用JSX语法将内容编译到JavaScript中。- react: 默认值,将JSX语法转换为React.createElement的调用,React16以前的标准方式 - react-jsx :该函数默认从react/jsx-runtime导入,react17引入的新模式,将JSX转换为对jsx函数的调用,提供更小体积的包,更好的tree shaking - react-jsxdev: react17引入,将JSX转换为对jsxDEV函数的调用,该函数默认从react/jsx-dev-runtime导入,主要用于开发环境,因为它提供了额外的运行时检查和开发帮助。 - preserve: 保留JSX语法不变,也就是说,.tsx文件将被编译为包含JSX语法的.js文件。这种模式通常与Babel等其他工具一起使用,这些工具可以在后续步骤中处理JSX -react-native: 专门为React Native设计的。在React Native中,JSX语法被直接支持,因此不需要转换为React.createElement或其他函数 | |
| jsxFactory:更改在使用经典 JSX 运行时编译 JSX 元素时,在文件中调用的函数。最常见的改动是为了使用像 ‘h’ 或 ‘preact.h’ 而非默认的 React.createElement,尤其是在使用诸如 Preact 这样的库时 | |
jsxFragmentFactory:指定在将 TypeScript JSX 代码编译为目标(如 React)时使用的 JSX 片段工厂函数,特别是在已经通过 jsxFactory 指定了 JSX 工厂函数的情况下。例如,可以指定 .Fragment 作为片段工厂 | |
| jsxImportSource:声明了在使用 jsx 为 "react-jsx" 或 "react-jsxdev"(TypeScript 4.1 引入的新特性)时,用于导入 JSX 和工厂函数的模块指定符。 - 随着 React 17 版本的发布,库支持了一种新的 JSX 转换形式,即通过单独的导入实现 | |
| lib:TypeScript 内置了一套针对 JavaScript 原生 API(如 Math)的标准类型定义 | 参考 15.3.6 lib 章节 |
| moduleDetection(模块检测):控制了TypeScript如何判断一个文件是脚本(script)还是模块(module) | - auto:默认值,不仅查找import和export语句,还会在使用 "module": "node" 或 "module": "nodenext" 且运行时,检查 package.json 文件中的 "type" 字段是否设置为 "module",同时,在使用 "jsx": "react-jsx" 进行编译时,也会检查当前文件是否为一个JSX文件- legacy: 仅依靠 import 和 export 语句来决定一个文件是否是模块 -force: 确保所有非声明文件都被当作模块处理 |
| noLib:true,禁用自动包含任何库文件。如果设置了此选项,lib 配置将被忽略 - TypeScript 编译器在没有为关键原始类型(如 Array、Boolean、Function、IArguments、Number、Object、RegExp、String 等)提供接口集的情况下无法进行编译。当你使用 noLib 时,预期你自己会提供这些基本类型的类型定义 | |
| target | 详情见15.3.5 |
| useDefineForClassFields:用于切换到即将推出的ECMAScript运行时行为(目前可忽略该配置项),当启用了 useDefineForClassFields,类字段的初始化时机和行为将遵循即将到来的ECMAScript标准,这可能与TypeScript早期版本的默认行为有所不同。 |
8 CompilerOptions配置=> Projects
| 描述 | 基础使用 |
|---|---|
| composite:true,施加了一些约束条件,使得构建工具(包括 TypeScript 自身在 --build 模式下)能够快速判断一个项目是否已经构建过 ,当开启此设置时 : - 未明确指定rootDir,则将其被设置为它的默认值包含在tsconfig.json中 - 所有实现文件必须被 include 模式匹配到或直接列在 files 数组中。如果违反了这个约束,tsc 编译器会告诉你哪些文件没有被指定 -declaration 默认设置为 true,意味着会自动生成声明文件(.d.ts | |
| disableReferencedProjectLoad(禁止自动加载项目引用到内存) | 在多项目类型的 TypeScript 程序中,TypeScript 为了给诸如“查找所有引用”这类需要完整知识图谱的编辑器响应提供准确的结果,会将所有可用的项目加载到内存中。如果项目非常大,可以使用 disableReferencedProjectLoad 配置项来禁止自动加载所有项目。这样一来,项目只会在你通过编辑器打开相关文件时动态地按需加载。 |
| disableSolutionSearching | 在使用组合(composite)TypeScript项目时,此配置项提供了一种方式来声明你不想让项目在使用诸如“查找所有引用”或编辑器中的“跳转到定义”等功能时被包含进来。此标志可用于提升大型组合项目的响应速度 |
| disableSourceOfProjectReferenceRedirect:禁用源项目引用重定向 | 略 |
| incremental | 略 |
| tsBuildInfoFile | 略 |
9 Completeness(完整性)
| 描述 | 基础使用 |
|---|---|
| skipDefaultLibCheck(跳过默认库检查) | 请改用 skipLibCheck。跳过默认库声明文件的类型检查 |
| skipLibCheck(跳过库检查):工程初始化默认开启了此配置项 | 此配置项可以在牺牲类型系统准确性的情况下节省编译时间。例如,两个库可能以不一致的方式定义了相同的接口或类型。TypeScript不会全面检查所有文件,而是仅仅检查应用程序源代码中明确引用到的代码,从而提高编译速度 |
弃用
| 描述 | 基础使用 |
|---|---|
| preserveValueImports(导入值保留) | 确保即使某些导入的值在编译后的 JavaScript 中看起来没有被直接使用,它们也会被保留在输出中 |
| reactNamespace(react命名空间),不再推荐使用,请改用 jsxFactory | 此配置原本用于指定在面向 TSX 文件(TypeScript 扩展的 JSX 文件)编译时调用的 React 类型对象,对应于 React.createElement 方法所在的命名空间 |