赞
踩
项目根目录包含 tsconfig.json 文件,表明该项目为 typescript 项目。
该文件一般位于根目录,并设定编译选项
JavaScript 项目类似功能文件是在根目录中设置 jsconfig.json 文件
我们知道 tsc 命令可以将一个 ts 文件编译为 js 文件
tsc [name].ts;
那么当我们开发一个项目的时候都是使用的 ts 开发的,难道需要手动用 tsc 去编译每个文件么?
不需要的。
只要在项目中初始化 tsconfig.json 文件,定义 tsc 的编译配置,此时执行 tsc 命令,会根据 tsconfig.json 配置文件自动
编译整个项目
tsc --init
执行以上命令生成 tsconfig.json 默认初始化文件
{ "compilerOptions": { /* 官网文档配置 https://aka.ms/tsconfig */ /* Projects */ "incremental": true, /* 保存 .tsbuildinfo 文件,增量编译 提高编译速度*/ "composite": true, /* 用于约束是否允许项目引用 */ "tsBuildInfoFile": "./.tsbuildinfo", /* 指定增量编译文件 .tsbuildinfo 存储路径 */ // "disableSourceOfProjectReferenceRedirect": true, /* 复合文件中使用声明文件而不是源文件 */ "disableSolutionSearching": true,/* 复合项目中,跳转到引用的定义位置*/ "disableReferencedProjectLoad": true,/*使用该标志来禁用引用项目的自动加载,在复合项目比较大的时候比较有用 */ /* Language and Environment */ "target": "es2016", /* 设置编译输出目标*/ "lib": [],/* 编译过程或运行时需要引入的库文件的列表*/ // "jsx": "preserve", /* jsx代码转换输出 */ // "experimentalDecorators": true, /* 实验性支持TC39 第二阶段decorators草案 */ // "emitDecoratorMetadata": true, /* 为源文件中的装饰器声明提交元数据设计类型 */ // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ // "reactNamespace": "", /* 指定调用'createElement'的对象.提交'react' JSX时应用 */ // "noLib": true,/* 禁用库文件,包括lib.d.ts */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ // "moduleDetection": "auto",/* Control what method is used to detect module-format JS files. */ /* Modules */ "module": "commonjs", /* 项目采用的模块化开发规范*/ "rootDir": "./", /* 设置文件的根目录,改变编译后文件的输出目录*/ "moduleResolution": "node", /* 指定模块的解析策略 */ "baseUrl": "./", /* 设置项目的基本路径*/ "paths": {}, /* 重新映射包的相对路径 */ "rootDirs": [], /* 当解析模块时,根目录下的多文件夹,可视作一个文件夹*/ "typeRoots": [], /* 设置声明文件的根目录*/ "types": [], /* 被引入项目的包的类型*/ "allowUmdGlobalAccess": true, /* 允许全局引入UMD模块 */ "moduleSuffixes": [],/* 解析文件名时使用的后缀 */ "resolveJsonModule": true,/* 允许引入.json文件 */ "noResolve": true,/* 不允许 import,require,reference 引用的文件被加载到项目中 */ /* JavaScript Support */ "allowJs": true,/*允许引入js文件*/ "checkJs": true,/* 会显示js文件错误提示*/ "maxNodeModuleJsDepth": 1,/* 在node_modules搜索文件夹与加载js文件的最大深度 */ /* Emit */ "declaration": true,/* 项目中的js或ts文件生成对应的js文件和 .d.ts 文件*/ "declarationMap": true,/* 产生 .d.ts文件对应的map文件*/ "emitDeclarationOnly": true,/*仅输出d.ts files并不生成js文件*/ "sourceMap": true,/* 创建生成js文件对应的map文件 */ "outFile": "./",/* 所有内容的输出文件.declaration为true时所有声明文件也都输出到一个 .d.ts 文件 */ "outDir": "./", /* 所有生成文件的输出目录*/ "removeComments": true,/* 输出文件中删除评论 */ "noEmit": true, /* 禁止Typescript编译器输出文件,使用三方规则 */ "importHelpers": true,/* 帮助全局引入一些兼容代码,而不是在每个文件中引入*/ "importsNotUsedAsValues": "remove",/* 说明imports的使用法师 */ "downlevelIteration": true, /* 代码降级,允许更多兼容性代码,使得新的代码能够在老的运行环境中运行 */ "sourceRoot": "",/* 说明调试的源代码的位置*/ "mapRoot": "", /* 说明调试器使用的map文件位置,并不是map的生成位置*/ "inlineSourceMap": true,/* 将map文件的内容内嵌到生成的js文件中 */ "inlineSources": true, /* 将源文件的内容也内嵌到map文件中,因此map文件与不内嵌源文件的内容是不同的*/ "emitBOM": true,/* 在输出文件的顶端生成UTF-8编码的字节顺序标记*/ "newLine": "crlf",/* 设置换行符使用的字符,Dos系统crlf,unix系统lf*/ "stripInternal": true, /* 删除@internal标签的声明*/ "noEmitHelpers": true, /* 禁用自动生成的兼容内容,可以自定义全局兼容内容 */ "noEmitOnError": true,/*报错情况下禁止生成文件*/ "preserveConstEnums": true,/* 保留 const enum 声明*/ "declarationDir": "./",/* 生成的声明文件的输出目录*/ "preserveValueImports": true,/* 输出文件中是否保留未使用的引入 */ /* Interop Constraints */ "isolatedModules": true,/* 该选项设置所有文件可以被安全引入*/ "allowSyntheticDefaultImports": true, /* 允许直接 'import x from y' 当没有默认导出时*/ "esModuleInterop": true, /* 输出额外代码支持更简易的方式导入 CommonJS 模块. */ "preserveSymlinks": true, /* 解析符号链接所在文件的相对位置,而不是符号链接的位置*/ "forceConsistentCasingInFileNames": true, /* 确保引入文件的正确性,文件名大小写敏感 */ /* Type Checking */ "strict": true, /* 允许strict类型检查 */ "noImplicitAny": true,/*是否可以设置any类型*/ "strictNullChecks": true, /*检查 null与undefined 的使用 */ "strictFunctionTypes": true,/* 函数赋值时确保参数类型与变量的类型的一致性*/ "strictBindCallApply": true, /* 检查函数使用bind, call, apply方法参数是否正确 */ "strictPropertyInitialization": true, /* 是否检查类的属性是否赋值*/ "noImplicitThis": true, /* 检查是否通过使用this隐式赋予'any'类型 */ "useUnknownInCatchVariables": true, /* 默认any类型的catch分支参数error是否需要设置为unknown */ "alwaysStrict": true, /* 文件最上添加 'use strict' 模式*/ "noUnusedLocals": true, /*未使用的局部变量报错*/ "noUnusedParameters": true, /* 未使用的参数报错 */ "exactOptionalPropertyTypes": true, /* 严格检查具有后缀?的接口或属性取值 */ "noImplicitReturns": true, /* 是否检查函数返回情况*/ "noFallthroughCasesInSwitch": true, /* 检查switch表达式的正确性,每个非空case都有break,或者return */ "noUncheckedIndexedAccess": true, /* 为未定义 默认string的obj.attr 添加 'undefined' 类型*/ "noImplicitOverride": true, /* 检查派生类重写的方法是否使用override 修饰符*/ "noPropertyAccessFromIndexSignature": true, /* 检查属性是否存在 */ "allowUnusedLabels": true, /*代码中的无效标签提示 */ "allowUnreachableCode": true, /*代码中的无效代码提示 */ /* Completeness */ "skipDefaultLibCheck": true, /* 可用 skipLibCheck替代*/ "skipLibCheck": true /* 是否跳过声明文件.d.ts 的类型检查 . */ } }
{ // 编译选项 "compilerOptions": { "outDir": "./output",// 编译生成文件的输出目录 "sourceMap": true, // 是否包含可以用于 debug 的 sourceMap // 以严格模式解析 "strict": true, "module": "esnext", "moduleResolution": "node", "target": "es5", // 允许从没有设置默认导出的模块中默认导入 "allowSyntheticDefaultImports": true, // 将每个文件作为单独的模块 "isolatedModules": false, // 启用装饰器 "experimentalDecorators": true, // 启用设计类型元数据(用于反射) "emitDecoratorMetadata": true, // 在表达式和声明上有隐含的any类型时报错 "noImplicitAny": false, "noImplicitReturns": true, "importHelpers": true,// 从 tslib 导入外部帮助库: 比如__extends,__rest等 "listFiles": true,// 编译过程中打印文件名 "removeComments": true,// 移除注释 "suppressImplicitAnyIndexErrors": true, // 允许编译javascript文件 "allowJs": true, // 解析非相对模块名的基准目录 "baseUrl": "./", "paths": { "jquery": [ "node_modules/jquery/dist/jquery" ] }, "lib": [ "dom", "es2015", "es2015.promise" ] } }
是对于 tsconfig.json 文件中的选项进行介绍,也即最外层的配置选项
顶级属性 | 描述 |
---|---|
compilerOptions | 编译器的配置选项 |
files | 程序包含的文件,若列表文件没找到会报错 |
include | 包含指定模式的系列文件 |
exclude | 排除系列文件,如 node_modules |
references | 构造更小项目碎片,改善打包/编辑的迭代时间 |
extends | 引入其它 tsconfig.json 文件 |
当程序包含的文件不多的时候使用 files 指定被编译文件的列表,若列表文件没找到会报错;只有需要编译的文件少时才会用到 files,如果需要编译的文件较多时使用 include
如果 tsconfig.json 文件引入其它配置文件,例如 base.json,可以继承 base.json 中的配置选项。如果有相同的配置项,tsconfig.json 采用就近原则,覆盖 base.json 中的配置项。不允许循环继承
include 与 exclude 可以使用通配符,指定一系列被编译或排除编译的文件
"references": [{ "@": "../src" }]
使用项目隔离的方式,可以改善类型检查或编译(代码变更)的效率
编译选项是配置文件中非常重要也比较复杂的配置选项,在 compilerOptions 中包含多个子选项,用来完成对编译的配置,因为 compilerOptions 选项较多,所以单独抽取一个章节详细介绍
compilerOptions 中的配置项可以根据作用进行分类,下面根据作用分别简介其中的配置项
属性 | 描述 |
---|---|
Type Checking 项目根据设置不符合要求会在错误报告中显示 | |
allowUnreachableCode | 代码中无效代码提示,undefined 警告,true 忽略,false 报错 |
allowUnusedLabels | 代码中无效标签提示,取值同上 |
alwaysStrict | 文件被严格模式解析,也就是每个文件最上添加 ‘use strict’ |
exactOptionalPropertyTypes | 是否需要检查项目中后缀添加?的属性的取值 |
noFallthroughCasesInSwitch | 检查 switch 表达式的正确性,每个非空 case 都有 break,或者 return |
noImplicitAny | 是否可以设置 any 类型 |
noImplicitOverride | 检查派生类重写的方法是否需要使用 override 修饰符,true 不需要要,false,必须有有修饰符,否则报错 |
noImplicitReturns | 是否检查函数返回情况 |
noImplicitThis | 是否检查通过使用 this 隐式赋予’any’类型 |
noPropertyAccessFromIndexSignature | 是否检查代码中使用了 obj.attr 语法获取未明确声明 attr 的值 |
noUncheckedIndexedAccess | 为未定义 默认 string 的 obj.attr 添加 ‘undefined’ 类型 |
noUnusedLocals | 未使用的局部变量报错 |
noUnusedParameters | 未使用的参数报错 |
strict | 严格模式 |
strictBindCallApply | 检查函数使用 bind, call, apply 方法参数是否正确 |
strictFunctionTypes | 函数赋值时确保参数类型与变量的类型的一致性 |
strictNullChecks | 检查 null 与 undefined 的情况 |
strictPropertyInitialization | 是否检查类的属性是否赋值 |
useUnknownInCatchVariables | 默认 any 类型的 catch 分支参数 error 是否需要设置为 unknown |
是否需要检查项目中后缀添加?的属性的取值,也即严格检查可选属性的类型
例如,
interface UserDefaults {
colorThemeOverride?: "dark" | "light";
}
如果设置 exactOptionalPropertyTypes:true,需要列出属性的可选值,
const settings = <UserDefaults>getUserDetail();
settings.colorThemeOverride 取值可以为"dark" 或 “light”,但是不能设置为"undefined",可以 settings 没有 colorThemeOverride 属性,以下两者不等价
settings = {
//可以
name: "",
age: ""
};
settings = {
//不可
name: "",
age: "",
colorThemeOverride: undefined
};
是否检查函数返回情况
若设置为 true,需要根据函数设置的返回类型检查函数的返回值,需要检查函数是否每个分支都有返回值,void 函数除外
是否检查 obj.attr
若设置为 true ,需要检查是否使用 object.attr 语法获取没有明确定义的属性。如果 attr 没有定义,使用该方式将会报错,可以通过 object[attr]方式获取该值;
若设置为 false ,则无需检查;
声明了 obj 类型,若是 obj.attr 是没有明确定义的属性
noUncheckedIndexedAccess 设置为 false ,则 attr 使用索引标记的方式设置为 string 类型;
noUncheckedIndexedAccess 设置为 true ,则 attr 使用索引标记的方式设置为 string|undefined 类型
为未定义的默认 string 的 obj.attr 添加 ‘undefined’ 类型
函数赋值时确保参数类型与变量的类型的一致性
function fn(x: string) {
console.log("Hello, " + x.toLowerCase());
}
type StringOrNumberFunc = (ns: string | number) => void;
// Unsafe assignment is prevented
let func: StringOrNumberFunc = fn;
检查 Null 与 undefined 的情况
是否检查类的属性是否赋值
当设置为 true 时,需要检查类的属性是否仅仅只是声明,没有赋值。
类 Class 中属性赋值的场景:
其它情况,默认为没有赋值情况,会有错误提示
当设置为 false 时,不检查
在 strict 模式下,是否需要设置 catch 语句中捕捉的 error 类型为 unknow,error 默认是 any 类型
当设置为 false 时,需要设置 error 类型:unknow,否则报错
try {
// ...
} catch (err: unknow) {
if (err instanceof Error) {
console.log(err.message);
}
}
当设置为 true 时,不需要设置 error 类型
try {
// ...
} catch (err) {
if (err instanceof Error) {
console.log(err.message);
}
}
属性 | 描述 |
---|---|
Modules 模块化设置 | |
allowUmdGlobalAccess | 允许全局引入 UMD 模块 |
baseUrl | 设置项目的基本路径 |
module | 项目使用的模块规范 |
moduleResolution | 指定模块的解析策略 |
moduleSuffixes | 解析 import 等文件名时使用的后缀 |
noResolve | 不允许 import,require,reference 引用的文件被加载到项目中 |
paths | 重新映射包的相对路径 |
resolveJsonModule | 解析引入.json 的静态文件 |
rootDir | 设置文件的根目录,改变编译后文件的输出目录 |
rootDirs | 解析模块时,根目录下的多文件夹,可视作一个文件夹 |
typeRoots | 设置声明文件的根目录 |
types | 设置 node_modules/@types 目录下会被项目加载的包的类型名 |
若为 true,则允许全局引入 UMD 模块
否则,需要每次 import 模块才可以使用
设置项目的基本路径,用于解析项目中的路径;
项目使用的模块化开发规范
指定模块的解析策略,也即如何处理模块
当 module 设置为 AMD, UMD, System or ES6/ES2015,moduleResolution 设置为 classic;
当 module 设置为 Commonjs,moduleResolution 设置为 node;
其它情况,moduleResolution 设置为 nodenext,node12;
resolveJsonModule 设置为 true,允许引入.json 文件;
node 正常情况下是允许引入.json 静态文件的
但是 typescript 默认不支持引入.json 静态文件,所以需要设置该选项
设置类型声明文件的根目录,默认情况下,包对应的类型文件是在 node_modules/@types 目录下,因此默认值是包含 node_modules/@types 的路径。
但是修改后则仅仅是修改后的路径下的类型文件,所有解析类型都会到 typeRoots 设置的目录列表中查询
设置可以使用的类型文件,例如默认情况下所有使用的包都到对应的 node_modules/@types 下查找对应的类型
但是一旦设定 types ,那么只有 types 指定列表中的包可以到 node_modules/@types 下查找对应的类型,其它的例如不在 types 设置的列表中,但是在 node_modules/@types 下的类型包,将不会被引入项目
属性 | 描述 |
---|---|
Emit 生成文件配置 | |
declaration | js/ts 文件生成对应的 js 文件和 d.ts 文件 |
declarationDir | 生成的声明文件的输出目录 |
declarationMap | 创建 d.ts 文件对应的 map 文件 |
emitDeclarationOnly | 仅输出 d.ts 文件并且不生成 js 文件 |
downlevelIteration | 允许程序在老环境中运行,生成兼容的降级代码 |
emitBOM | 在输出文件顶端是否生成字节顺序编码 |
importHelpers | 全局引入兼容代码,而不是在每个文件中引入 |
importsNotUsedAsValues | 决定 imports 的使用方式 |
inlineSourceMap | 将 map 文件的内容内嵌到生成的 js 文件中 |
inlineSources | 将源文件的内容内嵌到 map 文件中 |
mapRoot | 说明调试器使用的 map 文件位置 |
newLine | 设置换行字符,Dos 系统 crlf,unix 系统 lf |
noEmit | 不许默认编辑器生成 map 等文件,通过三方工具 |
noEmitHelpers | 禁用自动生成的兼容内容,可以自定义全局兼容内容 |
noEmitOnError | 报错时禁止编译生成文件 |
outDir | 所有生成文件的输出目录 |
outFile | 编译的输出文件,module 为 none/system/amd 时才可用 |
preserveConstEnums | 保留 const enum 声明 |
preserveValueImports | 输出文件中是否保留未使用的引入 |
removeComments | 输出文件中删除评论 |
sourceMap | 创建生成 js 文件对应的 map 文件 |
sourceRoot | 说明调试的源代码的位置 |
stripInternal | 删除@internal 标签的声明 |
项目中的 js 或 ts 文件编译成对应的 js 文件和 d.ts 声明文件
ts 文件如此没有任何问题,因为生成 js 文件的后缀名不同;但是 js 文件生成声明文件同时生成 js 文件就会存在问题,导致生成的 js 文件可能会覆盖原有的 js 文件,因此对于 js 项目,设置 emitDeclarationOnly,仅生成声明文件,防止覆盖问题
例如,.ts 文件
export let helloWorld = "hi";
生成 js 文件
export let helloWorld = "hi";
生成 d.ts 文件
export declare let helloWorld: string;
在编译的输出文件顶端插入 UTF-8 编码的字节序列标记,因为存在部分运行环境需要该序列标记说明 javascript 文件;该值取值默认是 false,如果没有特别的需要,最好不要改变该值
帮助全局引入一些兼容代码,而不是在每个文件中引入,例如从 tslib 导入外部帮助库**extends,**rest 等
export function fn(arr: number[]) {
const arr2 = [1, ...arr];
}
该代码使用了 ES6 的语法,可能在一些老的运行环境无法识别该代码,因此需要设置 downlevelIteration 为 true,允许编译时添加一些兼容性的代码
var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; export function fn(arr) { var arr2 = __spreadArray([1], __read(arr), false); }
此时如果没有设置 importHelpers 为 true,那么每个使用该 ES6 的语法处都会插入上述兼容性代码,导致很多重复性代码
如果设置 importHelpers 为 true
import { __read, __spreadArray } from "tslib";
export function fn(arr) {
var arr2 = __spreadArray([1], __read(arr), false);
}
如果你是自己编写该语法的兼容代码,可以设置 noEmitHelpers
主要是决定 import 的使用方式
就是允许生成 map 文件的前提下,map 文件的内容是内嵌到 js 文件中的
例如:
"use strict";
const helloWorld = "hi";
console.log(helloWorld);
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUMifQ==
outDir 用来指定编译后文件所在的目录
默认情况下,编译后的 js 文件会和 ts 文件位于相同的目录,设置 outDir 后可以改变编译后文件的位置
属性 | 描述 |
---|---|
JavaScript Support 选项 | |
allowJs | 允许引入 js 文件 |
checkJs | 会显示 js 文件错误提示 |
maxNodeModuleJsDepth | 在 node_modules 搜索文件夹与加载 js 的最大深度 |
属性 | 描述 |
---|---|
Editor 支持选项 | |
disableSizeLimit | 禁用项目分配的内存限制 |
plugins | 编辑器使用的语言服务插件 |
属性 | 描述 |
---|---|
allowSyntheticDefaultImports | 允许直接 import 非默认的导出 |
esModuleInterop | 输出额外代码支持更简易方式导入 CommonJS 模块 |
forceConsistentCasingInFileNames | 引入文件文件名大小写敏感 |
isolatedModules | 该选项设置所有文件可以被安全引入 |
preserveSymlinks | 解析符号链接所在文件相对位置,不是符号链接的位置 |
当一个模块没有默认导出时,我们一般使用
import * as React from "react";
但是当设置 allowSyntheticDefaultImports 为 true 时,可以使用以下方式
import React from "react";
如果该选项没有设置为 true 时,使用该方式导入没有默认导出的模块会报错
启用 esModuleInterop,也将会启用 allowSyntheticDefaultImports . esModuleInterop 默认值为 false;
esModuleInterop 设置为 true 时,将使用两个 helper 函数改变 import 模块时的转译规则,使得 es 模块可以使用 ES6 的简易方式加载 Commonjs 规范的模块
TypeScript 是大小写敏感的语言,介于引入文件的可能存在大小写敏感不确定,通过该选项可以设置
该选项设置所有文件可以安全引入,因为要求每个文件都是单独的模块
属性 | 描述 |
---|---|
设置编码,已废弃 | |
设置索引返回类型为 string ,已废弃 | |
noImplicitUseStrict | 禁用"use strict"模式 |
noStrictGenericChecks | 禁用泛型检查 |
向后兼容的输出文件,已废弃 | |
禁止额外的属性报错,已废弃 | |
suppressImplicitAnyIndexErrors | 禁止隐式 any 的报错 |
我们一般不使用该属性.默认情况下,我们提交模块文件到非 ES6 的环境,需要使用 UseStrict 模式,使用该属性禁止"use strict" 模式
在比较两个泛型函数时,TypeScript 将协调类型参数,该参数将会禁止检查
type A = <T, U>(x: T, y: U) => [T, U];
type B = <S>(x: S, y: S) => [S, S];
function f(a: A, b: B) {
b = a; // Ok
a = b; // Error 检查的情况
`Type 'B' is not assignable to type 'A'.
Types of parameters 'y' and 'y' are incompatible.
Type 'U' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'U'.`;
}
禁止额外的属性报错,例如:
type Point = { x: number; y: number };
const p: Point = { x: 1, y: 3, m: 10 };
`Type '{ x: number; y: number; m: number; }' is not assignable to type 'Point'.
Object literal may only specify known properties, and 'm' does not exist in type 'Point'.`;
已废弃
打开 suppressImplicitAnyIndexErrors
开关,禁止报告隐式 any 的错误,例如
const obj = { x: 10 };
console.log(obj["foo"]);
`
Element implicitly has an 'any' type because expression of type '"foo"' can't be used to index type '{ x: number; }'.
Property 'foo' does not exist on type '{ x: number; }'.`;
这种方式会全面禁止,推荐使用@ts-ignore
的方式
属性 | 描述 |
---|---|
emitDecoratorMetadata | 为装饰符提供元数据支持 |
experimentalDecorators | 支持 TC39 版本之前装饰符 |
jsx | 控制 jsx 构造函数 打包后的输出 |
jsxFactory | 工厂 |
jsxFragmentFactory | 工厂代码片段 |
jsxImportSource | 引入工厂的模块声明 |
lib | 库 |
moduleDetection | 模块检测 |
noLib | 禁用自动引入的库文件 |
reactNamespace | 声明对象 |
target | 编译的目标 |
useDefineForClassFields | 定义升级版本的 ClassFields |
默认值为 true,为模块中的装饰符提供实验性的元数据支持
示例:
function LogMethod(target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) {
console.log(target);
console.log(propertyKey);
console.log(descriptor);
}
class Demo {
@LogMethod
public foo(bar: number) {
// do nothing
}
}
const demo = new Demo();
emitDecoratorMetadata 不为 true:
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? (desc = Object.getOwnPropertyDescriptor(target, key)) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if ((d = decorators[i])) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([LogMethod], Demo.prototype, "foo", null); const demo = new Demo();
设置 emitDecoratorMetadata 为 true:
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? (desc = Object.getOwnPropertyDescriptor(target, key)) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if ((d = decorators[i])) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; function LogMethod(target, propertyKey, descriptor) { console.log(target); console.log(propertyKey); console.log(descriptor); } class Demo { foo(bar) { // do nothing } } __decorate([LogMethod, __metadata("design:type", Function), __metadata("design:paramtypes", [Number]), __metadata("design:returntype", void 0)], Demo.prototype, "foo", null); const demo = new Demo();
TC39 之后可以使用 emitDecoratorMetadata 支持装饰符,但是之前使用 experimentalDecorators
控制 jsx 的构造函数在 js 中的输出,只影响 tsx 文件中 jsx 相关代码在编译后在 js 的输出
示例:
.tsx 文件
export const HelloWorld = () => <h1>Hello world</h1>;
jsx=“react”,输出代码:
import React from "react";
export const HelloWorld = () => React.createElement("h1", null, "Hello world");
jsx=“react-jsx”,React 17 输出代码:
import { jsx as _jsx } from "react/jsx-runtime";
export const HelloWorld = () => _jsx("h1", { children: "Hello world" });
jsx=“react-jsxdev”,React 17 输出代码:
import { jsxDEV as _jsxDEV } from "react/jsx-dev-runtime";
const _jsxFileName = "/home/runner/work/TypeScript-Website/TypeScript-Website/index.tsx";
export const HelloWorld = () => _jsxDEV("h1", { children: "Hello world" }, void 0, false, { fileName: _jsxFileName, lineNumber: 9, columnNumber: 32 }, this);
jsx=“preserve||react-native”,因为不需要转换,因此输出代码:
export const HelloWorld = () => <h1>Hello world</h1>;
编译 jsx 元素时调用的方法,默认是 React.createElement
.tsx 文件:
export const HelloWorld = () => <h1>Hello world</h1>;
jsxFactory=“h”
const preact_1 = require("preact");
const HelloWorld = () => (0, preact_1.h)("div", null, "Hello");
jsxFragmentFactory 定义了当使用 jsxFactory 时 JSX 片段工厂调用的方法
tsconfig 配置
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment"
}
}
TSX 文件
import { h, Fragment } from "preact";
const HelloWorld = () => (
<>
<div>Hello</div>
</>
);
调用方法
const preact_1 = require("preact");
const HelloWorld = () => (0, preact_1.h)(preact_1.Fragment, null, (0, preact_1.h)("div", null, "Hello"));
在 TypeScript 4.1 后当使用 jsx =“react-jsx||react-jsxdev”
,声明引入 jsx 和 jsxs 工厂方法的模块
TSX 文件
import React from "react";
function App() {
return <h1>Hello World</h1>;
}
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react-jsx"
}
}
ts 编译后的 js 输出内容:
"use strict";
var __importDefault =
(this && this.__importDefault) ||
function (mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importDefault(require("react"));
function App() {
return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" });
}
{
"compilerOptions": {
"target": "esnext",
"module": "commonjs",
"jsx": "react-jsx",
"jsxImportSource": "preact", //添加
"types": ["preact"]
}
}
ts 编译后的 js 输出内容:
function App() {
return (0, jsx_runtime_1.jsx)("h1", { children: "Hello World" });
}
exports.App = App;
也可以通过注解的方式
/** @jsxImportSource preact*/
export function App() {
return <h1>Hello World</h1>;
}
检测模块
auto: Typescript 会检测 import/export 语句;当 module=“nodenext||node16"时会检测 package.json 中是否 type=” module ";并且当 jsx="react-jsx"会检测当前文件是否是 JSX 文件
legacy:通过 import/export 语句判断当前文件是否是模块 module
force:未声明的文件视作模块文件
禁用自动引入的库文件,如果设置了该选项会忽略 lib 选项的设置
当使用 noLib 时需要自定义 Array, Boolean, Function, IArguments, Number, Object, RegExp, String 类型,否则 Typescript 无法编译
target 用来指定 ts 被编译为的 ES 版本
target 的配置将会改变哪些 JS 特性会被降级,而哪些会被完整保留,用于保证代码在渲染环境中可以被正常渲染
例如,目前所有主流浏览器都支持 ES6,那么我们可以设定 target 为 es6,而如果部署的环境是比较老旧的环境。例如,如果 target 是 ES5 或更低版本,箭头函数 () => this 会被转换为等价的 函数 表达式
ESNext 值代表你的 TypeScript 所支持的最高版本。这个配置应当被谨慎使用,因为它在不同的 TypeScript 版本之间的含义不同,并且会导致升级更难预测
运行时需要引入的库
高级库
库 | 描述 |
---|---|
ES5 | ES3 和 ES5 的核心功能定义 |
ES2015 | ES2015 中额外提供的 API (别称 ES6) —— array.find, Promise,Proxy,Symbol,Map,Set,Reflect 等。 |
ES6 | ES2015 的别名。 |
ES2016 | ES2016 中额外提供的 API —— array.include 等。 |
ES7 | ES2016 的别名。 |
ES2017 | ES2017 中额外提供的 API —— Object.entries,Object.values,Atomics,SharedArrayBuffer,date.formatToParts,typed arrays 等。 |
ES2018 | ES2018 中额外提供的 API —— async iterables,promise.finally,Intl.PluralRules,rexexp.groups 等。 |
ES2019 | ES2019 中额外提供的 API —— array.flat,array.flatMap,Object.fromEntries,string.trimStart,string.trimEnd 等。 |
ES2020 | ES2020 中额外提供的 API —— string.matchAll 等。 |
ESNext | ESNext 中额外提供的 API —— 随着 JavaScript 的发展,这些会发生变化。 |
DOM | DOM 定义 —— window,document 等。 |
WebWorker | WebWorker 上下文中存在的 API。 |
ScriptHost | Windows Script Hosting Systems 的 API。 |
lib 用来指定项目中要用的库,一般在浏览器环境下不需要配置 lib,使用默认情况就好。修改库的情况,例如:
程序不运行在浏览器中,因此不需要"dom"库。
运行时平台提供了某些 JavaScript API 对象(也许通过 polyfill 支持),但还不支持某个 ECMAScript 版本的完整语法时。
有一些 (但不是全部)对于更高级别的 ECMAScript 版本的 polyfill 或本地实现。
属性 | 描述 |
---|---|
调试时输出策略信息 | |
explainFiles | 打印编译相关文件名称,取值true/false |
extendedDiagnostics | 可以用于了解编译性能 |
generateCpuProfile | 生成CPU运行缓慢概况 |
listEmittedFiles | 打印编译生成文件名称 |
listFiles | 打印编译文件名称,可以用于查看文件是否被编译 |
traceResolution | 用于调试模块未被引用的原因,取值true/false |
属性 | 描述 |
---|---|
composite | 强制执行某些约束 |
disableReferencedProjectLoad | 复合项目中设置是否自动加载所有项目 |
disableSolutionSearching | 复合项目是否允许跳转到引用的定义位置 |
disableSourceOfProjectReferenceRedirect | 复合项目中是引用源文件还是声明文件 |
incremental | 将上次编译的信息保存到磁盘文件中 |
tsBuildInfoFile | 指定存储增量编译信息的文件 |
属性 | 描述 |
---|---|
noErrorTruncation | 没有错误信息截断,true:不截断 false:截断 |
preserveWatchOutput | 每次发生变更时观察模式下是否清空历史console信息 |
pretty | 编译时使用用颜色和上下文展示错误和信息 |
属性 | 描述 |
---|---|
skipDefaultLibCheck | 用skipLibCheck代替 |
skipLibCheck | 是否跳过声明文件的类型检查 |
通过观察选项设置告诉编译器或语言服务应该采用哪种策略来跟踪文件和目录更改
{
"watchOptions": {}
}
属性 | 描述 |
---|---|
watchOptions | |
assumeChangesOnlyAffectDirectDependencies | 用于设置是否只有直接变更的文件或者直接引用变更文件的文件被重检测/重编译 |
watchFile | 设置如何监视文件 |
watchDirectory | 缺乏递归文件监视功能的系统中如何监视整个目录树的策略 |
fallbackPolling | 当使用文件系统事件时,无本地轮询策略可用时的策略 |
synchronousWatchDirectory | 本地不支持递归监视的平台上,同步调用回调并更新目录监视器的状态,而不是在一个小的时间内同一文件上发生多次编辑 |
excludeDirectories | 设置被排除监视变更的文件夹 |
excludeFiles | 设置被排除监视变更的文件 |
设置如何监视文件
缺乏递归文件监视功能的系统中如何监视整个目录树的策略
当使用文件系统事件时,此选项指定了当系统 用完本机文件监视器或不支持本机文件监视器时 使用的轮询策略。
{
"typeAcquisition": {
"enable": false
}
}
类型获取选项仅对javascript项目比较重要,因为TypeScript项目需要明确定义类型
属性 | 描述 |
---|---|
typeAcquisition | |
enable | js项目是否禁用类型自动引入 |
include | js项目中ts需要额外指引以明确全局依赖 |
exclude | js项目中指定模块禁止引入类型 |
disableFilenameBasedTypeAcquisition | 禁止根据文件名自动引入类型定义 |
{
"typeAcquisition": {
"enable": false,
"include": ["jquery"],
"exclude": ["jest", "mocha"],
"disableFilenameBasedTypeAcquisition": true
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。