我们都知道ts不能直接放在浏览器中,但是js可以
每一个ts要执行tsc .ts文件
但是一旦ts文件一多,一个一个编译太麻烦了,所以:

编译选项

  • 自动编译文件

    • 编译文件时,使用-w指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件重新编译。
    • 示例tsc xxx.ts -w
      1. tsc xxx.ts -w
  • 自动编译整个项目

    • 如果直接使用tsc指令,则可以自动将当前项目下的所有ts文件编译为js文件。
    • 但是能直接使用tsc命令的前提时,要先在项目根目录下创建一个ts文件tsconfig.json(tsconfig.json是ts编译器的一个编译文件,ts编译器可以根据它的信息来对代码进行编译)
    • tsconfig.json是一个json文件,添加配置文件后,只需tsc命令即可完成对整个项目的编译
    • 配置选项:

      • include(包含)

        • 定义希望被编译文件所在的目录
        • 默认值:[“*/“]
        • 示例:

            1. "include":["src/**/*","test/**/*"]
          • 上述示例中,所有src目录和test目录下的文件都会被编译

      • exclude

        • 定义需要排除在外的目录
        • 默认值:[“node_modules”,”bower_components”,”jspm_packages”]
        • 示例:

            1. "exclude":["./src/hello/**/*"]
            1. 配置文件的作用就是来配置我们这个ts的一些编译信息的,它会根据编译信息根据来进行编译

创建tsconfig.json

  1. {
  2. "compilerOptions": {
  3. "module": "commonjs",
  4. "target": "ES5",
  5. "sourceMap": true
  6. },
  7. "exclude":[
  8. "node_modules"
  9. ]
  10. }

你也可以:

  1. {
  2. }

有了tsconfig.json文件,你直接执行tsc就可以执行所有的ts文件
这个默认是编译所有ts文件,但是我们在真正开发过程中不是所有的ts都是要经过编译的。

include(主要记住)

包含

  1. {
  2. /*
  3. include:包含
  4. 就是来指定哪些ts文件需要被编译
  5. */
  6. "include":[
  7. "./src/**/*",// ./src/**/* | *:表示任意文件 | **:表示任意的目录
  8. ]
  9. }

创建/src目录,在下面添加app.ts

  1. let a: number|String = 1
  2. console.log(a);

执行tsc发现只对src下的文件编译成js,文件外的ts没有编译成js

include表示指定我们要编译的文件

exclude

不包含

  1. {
  2. "include":[...],
  3. "exclude":[]
  4. }

有一些文件即便是在包含的src里面,但是我们不希望被编译的,就可以用exclude进行排除,怎么写?

  1. {
  2. "include": [...],//包含的目录里的所有文件进行ts编译
  3. "exclude": ["./src/hello/**/*"],//表示我除了hello下的文件
  4. }

默认要排除的文件是这些:

  • node_modules
  • bower_components
  • jspm_packages

exclude表示不需要被编译的文件目录

extends

继承:说白了就是**当我们的配置文件特别复杂的时候,而且不想重复写**
**tsconfig.json****xxx.json**,我想把**xxx.json**放入**tsconfig.json**,但是我又不想再在写一遍,就可以用**extends**去继承一下。就像是我们引入一个外部文件是一样的
示例:

  1. {
  2. "include": [...],//包含的目录里的所有文件进行ts编译
  3. "exclude": [...],//表示哪些文件不进行ts编译
  4. "extends": "./configs/base"
  5. }

files

文件
指定被编译文件的列表,只有需要编译的文件少时才用到
示例:

  1. {
  2. "include": [...],//包含的目录里的所有文件进行ts编译
  3. "exclude": [...],//表示哪些文件不进行ts编译
  4. "extends": "./configs/base",//引入外部配置
  5. "files": [
  6. "core.ts",
  7. "sys.ts",
  8. ...
  9. ],
  10. }

compilerOptions(最最重要)

编译器的选项

  1. {
  2. ...
  3. "compilerOption":{},
  4. }

里面有很多的子选项:

target

目标
target用来指定ts被编译的版本
最明显的是
ts:

  1. let a:number = 1;

经过tsc编译为js的时候let就被编译为var:

  1. var a = 1;

就是因为是默认情况下ts会转换成es3版本的js。为什么转换成es3?

因为es3比较老,但是它兼容性比较好,所有浏览器都支持

修改es版本

  1. {
  2. ...
  3. "compilerOption":{
  4. "target": "ES6"
  5. }
  6. }

这时候会发现ts里面是let a,js里面也是let a
target里面能写的就是es的版本
如果不知到写什么,有一个办法:

就是不知道版本瞎写

  1. {
  2. ...
  3. "compilerOption":{
  4. "target": "abc"
  5. }
  6. }

使用tsc编译的时候就会报错:

  1. Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext'.

里面就是target里面能接收到的值

module

模块
最开始的js是没有模块化的概念,但是后来js对它进行模块化的拓展加强以至于后来es6都有了自己的模块化,就导致在js中有着各种各样的不同版本模块化的解决方案。所以最终你想要编译的js是哪种模块化的解决方案?

通过module来设置

module:就是来指定使用的模块化的规范

先随便写:

  1. {
  2. ...
  3. "compilerOption":{
  4. "target": "ES6",
  5. "module": "abc",
  6. }
  7. }

然后,整一个模块化的ts文件:

  1. //导出内容
  2. export const hi:string = "你好";

然后在app.ts里面导入这个模块:

  1. import {hi} from './m.js'
  2. let a: number|String = 1
  3. console.log(a);

报的错:

  1. Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node12', 'nodenext'.

所以我们改tsconfig.json

  1. {
  2. ...
  3. "compilerOption":{
  4. "target": "ES6",
  5. "module": "ES6",
  6. }
  7. }
  1. let a = 1;
  2. console.log(a);
  3. export {};

由于我的hi没有使用,所以在./src/app.js里面看不到那个hi
所以我们打印一下:

  1. import {hi} from './m.js'
  2. let a: number|String = 1
  3. console.log(a);
  4. console.log(hi)

重新编译:

  1. import { hi } from 'm.js';
  2. let a = 1;
  3. console.log(a);
  4. console.log(hi);

这里就使用了es6的模块化标准

lib

lib(library):用来指定项目中使用的库
我们一般情况下是不动它的。
因为像js会用到很多第三方库: 比如我们经常操作的DOM(document)
lib表示来指定你的项目里面想要用到哪些库
没有lib:document有提示信息;有lib:document就没有提示信息了
若是有lib但是你还想用DOM,可以:

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "lib": ["DOM"]
  7. }
  8. }

所以lib一般情况下我们不需要改,什么时候需要动他?

我的代码不是在浏览器的环境中运行的,而是在nodejs环境中运行,里面没有dom,那你可以去修改它

lib我可以填哪些东西?

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "lib": ["xxx"]//随便写一个
  7. }
  8. }

重新编译:

  1. Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'es2018', 'es2019', 'es2020', 'es2021', 'esnext', 'dom', 'dom.iterable', 'webworker', 'webworker.importscripts', 'webworker.iterable', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory', 'es2017.string', 'es2017.intl', 'es2017.typedarrays', 'es2018.asyncgenerator', 'es2018.asynciterable', 'es2018.intl', 'es2018.promise', 'es2018.regexp', 'es2019.array', 'es2019.object', 'es2019.string', 'es2019.symbol', 'es2020.bigint', 'es2020.promise', 'es2020.sharedmemory', 'es2020.string', 'es2020.symbol.wellknown', 'es2020.intl', 'es2021.promise', 'es2021.string', 'es2021.weakref', 'es2021.intl', 'esnext.array', 'esnext.symbol', 'esnext.asynciterable', 'esnext.intl', 'esnext.bigint', 'esnext.string', 'esnext.promise', 'esnext.weakref'.

一般情况下不用动它

lib:指定浏览器当中所要指定的一个库。默认允许的环境就是我们浏览器所需要的运行环境

outDir

include:哪些文件夹里面的代码需要被我们es编辑器所解析,解析完后在哪呢?
有些时候我不希望ts文件js文件在一起
我们就会设置一个目录去放编译后的文件,这就是我们outDir的作用
**outDir**: 用来指定编译后文件所在的目录

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "outDir": "./dist"
  7. }
  8. }

outFile(了解)

我们输出的文件
**outFile**: 将我们的代码合并为一个文件
修改m.tsapp.ts

app.ts

  1. let a: number|String = 1
  2. console.log(a);

m.ts

  1. let b:number = 20
  2. let c:string = 'hello'
  3. console.log(b,c)

tsconfig.json

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "outDir": "./dist",
  7. "outFile": "./dist/app.js"
  8. }
  9. }

就是说,我要把代码合并到app.js当中
在运行前先把dist目录先删了
现在我们再执行以下编译tsc
会有报错,先不看报错,看dist文件目录下只有一个app.js
设置**outFile**后,所有的全局作用域中的代码会合并到同一个文件中

如果将ts中的模块化整上,你就整不上了

  1. Only 'amd' and 'system' modules are supported alongside --outFile.

意思是:如果你想要把多个模块给它合并成一个文件,你必须使用模块化规范,必须是amd或者system

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "system",
  6. "outDir": "./dist",
  7. "outFile": "./dist/app.js"
  8. }
  9. }

我们在这里用的不多。因为这个不灵活,实际上这种应该结合打包工具去使用的

allowJs

allow:允许,js:js

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "outDir": "./dist",
  7. //是否对我们js文件进行编译,默认是false
  8. "allowJs": false
  9. }
  10. }

在我们src目录下创建hello.js执行编译,发现没有进dist目录下

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "outDir": "./dist",
  7. //是否对我们js文件进行编译,默认是false
  8. "allowJs": true
  9. }
  10. }

checkJs

是否检查js代码的语法是否符合语法规范,默认是false

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. "outDir": "./dist",
  7. "allowJs": true,
  8. "checkJs": false
  9. }
  10. }

removeComments

是否移除注释

noEmit

不生成编译后的文件
有些时候,就是我不想ts的编译功能,只想用ts去检查一下语法
其实使用几率不是那么大

onEmitOnError

也是不生成js代码,但是这个有一个前提条件,就是当有错误的时候,不生成编译后的文件

语法检查的

alwaysStrict

严格模式的语法
怎么开启严格模式
js文件为例:手动加上一个字符串

  1. "use strict"
  2. let b = 20;
  3. let c = 'hello';

这就表示开启了我们的严格模式
在ts文件下进行编译的时候,是不会带严格模式,但凡,我们需要在ts里面使用严格模式就会用到alwaysStrict
**alwaysStrict**:用来设置编译后的文件是否使用严格模式,默认是false

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. // "lib": ["ES6","DOM"],
  7. "outDir": "./dist",
  8. // "outFile": "./dist/app.js"
  9. "alwaysStrict": true
  10. }
  11. }

就会默认在一个严格模式下了

noImplicitAny

Any我们都知道是ts中的一个类型,当我们整一个变量不指定类型,这个变量的默认类型就是any

  1. function fun(a,b){
  2. return a+b
  3. }

any一旦设置实际上就关闭了我们ts对所有类型的检查,所以我们是不推荐使用any的,但是我们使用了any,ts中没有任何的报错,这时候帮我们检查是否有隐式的any的时候,我们就可以使用noImplicitAny

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. // "lib": ["ES6","DOM"],
  7. "outDir": "./dist",
  8. // "outFile": "./dist/app.js"
  9. "noImplicitAny": true
  10. }
  11. }

上面隐式的any就会报错

**noImplicitAny**:不允许隐式的any

noImplicitThis

**noImplicitAny**类似
不允许不明确类型的this

  1. function fun2(){
  2. alert(this)
  3. }

你不确定this是什么;你用到的方法它没有,那这个时候,我们就希望ts编译器它可以把这个错误和隐患给我们检查出来

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. // "lib": ["ES6","DOM"],
  7. "outDir": "./dist",
  8. // "outFile": "./dist/app.js"
  9. "noImplicitAny": true,
  10. "noImplicitThis": true
  11. }
  12. }

这时this就报错了
说白了我不明确这个this到底是什么
怎么解决这个问题

  1. function fun2(this:any){
  2. alert(this)
  3. }

或是知道是一个window:

  1. function fun2(this:Window){
  2. alert(this)
  3. }

不允许不明确类型的this

strictNullChecks

严格的检查空值

  1. let box1 = document.getElementById('box1');
  2. box1.addEventListener('click',function(){
  3. alert('hello');
  4. })

这是js中很简单的点击事件,但是,我确定这个box1这个元素浏览器里有吗?
可能box1不存在,不存在的话,就是null,可能会报错。但是ts编译器没有给我检查出来这个问题,就是因为strictNullChecks没有设置为true提醒我

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. // "lib": ["ES6","DOM"],
  7. "outDir": "./dist",
  8. // "outFile": "./dist/app.js"
  9. "noImplicitAny": true,
  10. "noImplicitThis": true,
  11. "strictNullChecks": true
  12. }
  13. }

就会给你提示:

  1. box1对象可能为null

怎么解决这个问题?
可以做一个判断:

  1. let box1 = document.getElementById('box1');
  2. if(box1 != null){
  3. box1.addEventListener('click',function(){
  4. alert('hello');
  5. })
  6. }

或者

  1. let box1 = document.getElementById('box1');
  2. box1?.addEventListener('click',function(){
  3. alert('hello');
  4. })

strict

所有严格检查的总开关
这个如果为true,以上几个严格语法检查全部打开
也就是:

  1. {
  2. ...
  3. "compilerOptions": {
  4. "target": "ES6",
  5. "module": "ES6",
  6. // "lib": ["ES6","DOM"],
  7. "outDir": "./dist",
  8. // "outFile": "./dist/app.js"
  9. "strict": true,
  10. /*
  11. stricttrue,以下的几个严格检查都可以省略不写
  12. "noImplicitAny": true,
  13. "noImplicitThis": true,
  14. "strictNullChecks": true
  15. */
  16. }
  17. }

一般开发建议,改为true

其实配置还有很多,一边学一边用

关于配置选项就列举这么多