您现在的位置是:首页 >技术教程 >TypeScript 配置简述网站首页技术教程
TypeScript 配置简述
TypeScript 配置简述
初始化项目的过程为:
-
新建一个项目
这里使用
yarn init -y
去创建一个 node 项目,随后使用yarn add typescript
下载 TS 的依赖 -
新建一个 ts 文件
console.log('test');
随意 log 一点东西进行测试
-
使用
tsc
编译 ts 文件❯ yarn tsc app.ts yarn run v1.22.19 $ /Users/study/ts-study/tsconfig/node_modules/.bin/tsc app.ts ✨ Done in 2.25s.
-
添加 index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <script src="./app.js"></script> </body> </html>
其他不是重点,主要需要在 html 文件中引入编译好的 js 文件,最后运行结果如下:
这里使用 live server 开了一个服务器,这样一旦 js 文件更新了 console 就会立即更新。不用 live server 手动刷新也行
watch mode
直接使用 tsc <filename> -w
可以进入 watch mode,这样一旦文件产生了变化就会自动重新编译:
❯ yarn tsc app.ts -w
[7:33:40 PM] Starting compilation in watch mode...
[7:33:41 PM] Found 0 errors. Watching for file changes.
[7:34:05 PM] File change detected. Starting incremental compilation...
[7:34:06 PM] Found 0 errors. Watching for file changes.
如果只是想要泡一两个文件的话,可以直接使用 watch mode,但是文件一旦多了就比较难以管理。
编译多个文件
想要能够编译多个 ts 文件,首先需要初始化 ts 的配置:
❯ yarn tsc --init
yarn run v1.22.19
$ /Users/study/ts-study/tsconfig/node_modules/.bin/tsc --init
Created a new tsconfig.json with:
TS
target: es2016
module: commonjs
strict: true
esModuleInterop: true
skipLibCheck: true
forceConsistentCasingInFileNames: true
You can learn more at https://aka.ms/tsconfig
✨ Done in 1.15s.
不知道是不是 tsconfig 新增的,现在初始化后还挺……好看的……?
运行完毕后就会出现一个 tsconfig.json
的配置文件:
这个文件很长,大多数的内容都是注释掉的,之后主要会讲一些比较主要且通用的功能。我目前版本的完整配置如下:
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig to read more about this file */
/* Projects */
// "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "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": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
// "noLib": true, /* Disable including any library files, including the default 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" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
// "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
// "resolveJsonModule": true, /* Enable importing .json files. */
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
不过一旦初始化了之后,再运行 tsc 就会默认监测当前项目下所有的 ts 文件。
-
包含和移除的文件
这两个是配置文件的
include
和exclude
属性,大致结构如下:{ "compilerOptions": {}, "include": ["src/"], "exclude": ["node_modules"] }
被加到
exclude
中的文件不会被 tsc 监测并且重新编译,ts 只会编译include
中的文件。这两个属性可以做文件的匹配,假设有一些配置文件不想被编译,那么可以将
**/*.config.ts
放到exclude
数组中,这样 ts 就会忽略所有文件夹下,包含XX.config.ts
的文件。另一个比较常见的配置就是
node_modules
,虽然这个文件夹默认是忽略的。另外,如果有专门运行测试的脚本,那么有些情况下也会在编译的选项中将所有的测试文件给忽略掉。
ts 最后被编译的文件是 includes 中减去 excludes 的文件。
-
target
target 指的是最终 JavaScript 会被编译的版本,现在的默认版本是 es2016,也就是 ES7,除了常见的 ES6 的功能之外,多了一个
**
和includes
的支持,一些比较简单的例子如下:ES7:
ES6 会无法转换
includes
这个函数,因此报错:ES5:
对于一些函数,TS 可以有效地转换成早期的实现,不过看到
includes
就报错了,因此如果项目比较大的话,还是建议使用 babel 进行转译而非完全依赖 TS。 -
lib
lib 指的是 TS 需要包含的包,默认情况下它会包含所有 target 包含的 lib 和 DOM 对象。
例如说之前将项目指定成 ES5 的时候,因为 lib 中不包含 ES2016.Array.Include,TS 就会报错,并且建议至少修改 target 的版本。一般情况下这个配置是被 comment 掉的,如果是 uncomment 的情况下,就必须要将所有使用的 lib 全都列举出来,否则 ts 任何的 lib 都不会知道(包括 console.log),大多数情况下使用默认配置就够了。
具体的配置可以在 https://www.typescriptlang.org/tsconfig#lib 中查看。
-
js 相关
这里主要有两个配置:
allowJs
和checkJs
,前者开启 JS TS 混用,即允许 TS 项目中存在并运行 JS 文件,后者则是会开启对 JS 文件的检查。默认情况下 TS 文件中无法混用 JS:
如果想要逐步将 JS 替换成 TS,可以开启这两个配置进行逐步替代。
-
sourcemap
sourcemap 是一个比较重要的点,它会开启编译后的 JS 和 TS 文件之间的关联,可以直接 debug TS 文件而非 JS 文件,之前在使用 vscode 的 debugger 时就因为没有开启 sourcemap 无法建立关联,所有的断点都是灰色的无法被激活。
其建立的方法是创建一个
<filename>.js.map
的文件,其中包含必要的映射。 -
outdir/rootdir
root folder 指的是项目代码入口所在的文件夹,比如说比较流行一点的框架都喜欢把源码放到
src
下面,然后将打包的代码放到dist
或是build
下面,如:{ "compilerOptions": { "outDir": "./dist", "rootDir": "./src" } }
配置完后:
rootDir 还有一个相似的属性是 rootDirs,接受一个数组作为参数,可以接受多个 entry。
-
报错后不编译
noEmitOnError
的选项,开启后 TS 将不会继续进行编译。 -
严格模式
即 strict 为 true,它会默认开启下面所有的验证。
-
noImplicitAny
这个主要在循环体、获取函数变量,如果不声明变量的类型就会报错,如:
和
// ⬇️ explict any 报错 const func = (data) => { // ⬇️ explicit any 报错 const obj = {}; for (let val of data) { obj[val] = val; } };
-
strict null
TS 在这里会对可能是 null/undefined 的变量报错,如:
这种情况下要么使用 if/else 包一下,要么使用 optional chaining,另一个小技巧就是使用
!
:!
告诉 TS 这个值肯定会存在其他的选项我用的就比较少了,这里不多赘述。
-
-
removeComments
将 TS 文件编译成 JS 文件时去除注释
-
noEmit
TS 将不会编译成 JS 文件,不过仍然会进行检查
这个比较适合本身如果搭配 babel,只需要 TS 进行语法检查的配置
-
downlevelIteration
将
for of
循环转换成for (var i...)
循环,适合需要老版本兼容的项目for of
具体什么版本出来的我不记得了,但是其语法是迭代 iterable 对象,所以肯定是 ES6 以后的语法。 -
isolatedModules
这个配置可以让所有的文件单独被编译,无需依赖其他的文件,这个主要是针对其他的转译器编译时可能造成的运行时错误进行的优化。
简单的说就是,哪怕是个空文件,为了防止报错都得丢个
export {}
的语法。
debug
这里使用 VSCode 的 debugger,首先确定 sourcemap 的配置是 true,这个时候至少可以在浏览器中使用 debugger 了。
另一个要修改的地方是 vscode 的 debug 设置,这个有点取决于具体的项目,初始化的配置如下:
鉴于目前的测试项目在浏览器中运行,这里就会选择 chrome 浏览器进行 debug,然后 vscode 就会自动生成一个配置文件:
将 url 改成对应的服务端口(这里使用 live server,也就是 5500),这样就可以在 vscode 中进行 debug 了: