我们都知道ts
不能直接放在浏览器中,但是js
可以
每一个ts
要执行tsc .ts文件
但是一旦ts
文件一多,一个一个编译太麻烦了,所以:
编译选项
自动编译文件
- 编译文件时,使用
-w
指令后,TS编译器会自动监视文件的变化,并在文件发生变化时对文件重新编译。 - 示例tsc xxx.ts -w
tsc xxx.ts -w
- 编译文件时,使用
自动编译整个项目
- 如果直接使用
tsc
指令,则可以自动将当前项目下的所有ts文件编译为js文件。 - 但是能直接使用
tsc
命令的前提时,要先在项目根目录下创建一个ts文件tsconfig.json
(tsconfig.json是ts编译器的一个编译文件,ts编译器可以根据它的信息来对代码进行编译) tsconfig.json
是一个json
文件,添加配置文件后,只需tsc命令即可完成对整个项目的编译配置选项:
include(包含)
- 定义希望被编译文件所在的目录
- 默认值:[“*/“]
示例:
"include":["src/**/*","test/**/*"]
上述示例中,所有src目录和test目录下的文件都会被编译
exclude
- 定义需要排除在外的目录
- 默认值:[“node_modules”,”bower_components”,”jspm_packages”]
示例:
"exclude":["./src/hello/**/*"]
配置文件的作用就是来配置我们这个ts的一些编译信息的,它会根据编译信息根据来进行编译
- 如果直接使用
创建tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "ES5",
"sourceMap": true
},
"exclude":[
"node_modules"
]
}
你也可以:
{
}
有了tsconfig.json
文件,你直接执行tsc就可以执行所有的ts文件
这个默认是编译所有ts文件
,但是我们在真正开发过程中不是所有的ts都是要经过编译的。
include(主要记住)
包含
{
/*
include:包含
就是来指定哪些ts文件需要被编译
*/
"include":[
"./src/**/*",// ./src/**/* | *:表示任意文件 | **:表示任意的目录
]
}
创建/src
目录,在下面添加app.ts
let a: number|String = 1
console.log(a);
执行tsc
发现只对src下的文件编译成js
,文件外的ts
没有编译成js
include表示指定我们要编译的文件
exclude
不包含
{
"include":[...],
"exclude":[]
}
有一些文件即便是在包含的src里面,但是我们不希望被编译的,就可以用exclude
进行排除,怎么写?
{
"include": [...],//包含的目录里的所有文件进行ts编译
"exclude": ["./src/hello/**/*"],//表示我除了hello下的文件
}
默认要排除的文件是这些:
- node_modules
- bower_components
- jspm_packages
exclude表示不需要被编译的文件目录
extends
继承:说白了就是**当我们的配置文件特别复杂的时候,而且不想重复写**
有**tsconfig.json**
和**xxx.json**
,我想把**xxx.json**
放入**tsconfig.json**
,但是我又不想再在写一遍,就可以用**extends**
去继承一下。就像是我们引入一个外部文件是一样的
示例:
{
"include": [...],//包含的目录里的所有文件进行ts编译
"exclude": [...],//表示哪些文件不进行ts编译
"extends": "./configs/base"
}
files
文件
指定被编译文件的列表,只有需要编译的文件少时才用到
示例:
{
"include": [...],//包含的目录里的所有文件进行ts编译
"exclude": [...],//表示哪些文件不进行ts编译
"extends": "./configs/base",//引入外部配置
"files": [
"core.ts",
"sys.ts",
...
],
}
compilerOptions(最最重要)
编译器的选项
{
...
"compilerOption":{},
}
里面有很多的子选项:
target
目标
target用来指定ts被编译的版本
最明显的是
ts:
let a:number = 1;
经过tsc
编译为js
的时候let
就被编译为var
:
var a = 1;
就是因为是默认情况下ts
会转换成es3
版本的js。为什么转换成es3
?
因为es3比较老,但是它兼容性比较好,所有浏览器都支持
修改es版本
{
...
"compilerOption":{
"target": "ES6"
}
}
这时候会发现ts
里面是let a
,js里面也是let a
target里面能写的就是es的版本
如果不知到写什么,有一个办法:
就是不知道版本瞎写
{
...
"compilerOption":{
"target": "abc"
}
}
使用tsc
编译的时候就会报错:
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:就是来指定使用的模块化的规范
先随便写:
{
...
"compilerOption":{
"target": "ES6",
"module": "abc",
}
}
然后,整一个模块化的ts文件:
//导出内容
export const hi:string = "你好";
然后在app.ts
里面导入这个模块:
import {hi} from './m.js'
let a: number|String = 1
console.log(a);
报的错:
Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015', 'es2020', 'es2022', 'esnext', 'node12', 'nodenext'.
所以我们改tsconfig.json
{
...
"compilerOption":{
"target": "ES6",
"module": "ES6",
}
}
let a = 1;
console.log(a);
export {};
由于我的hi
没有使用,所以在./src/app.js
里面看不到那个hi
所以我们打印一下:
import {hi} from './m.js'
let a: number|String = 1
console.log(a);
console.log(hi)
重新编译:
import { hi } from 'm.js';
let a = 1;
console.log(a);
console.log(hi);
这里就使用了es6的模块化标准
lib
lib(library):用来指定项目中使用的库
我们一般情况下是不动它的。
因为像js会用到很多第三方库: 比如我们经常操作的DOM(document)
lib表示来指定你的项目里面想要用到哪些库
没有lib:document有提示信息;有lib:document就没有提示信息了
若是有lib但是你还想用DOM,可以:
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"lib": ["DOM"]
}
}
所以lib一般情况下我们不需要改,什么时候需要动他?
我的代码不是在浏览器的环境中运行的,而是在nodejs环境中运行,里面没有dom,那你可以去修改它
lib我可以填哪些东西?
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"lib": ["xxx"]//随便写一个
}
}
重新编译:
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**
: 用来指定编译后文件所在的目录
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"outDir": "./dist"
}
}
outFile(了解)
我们输出的文件**outFile**
: 将我们的代码合并为一个文件
修改m.ts
和app.ts
app.ts
let a: number|String = 1
console.log(a);
m.ts
let b:number = 20
let c:string = 'hello'
console.log(b,c)
tsconfig.json
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"outDir": "./dist",
"outFile": "./dist/app.js"
}
}
就是说,我要把代码合并到app.js
当中
在运行前先把dist
目录先删了
现在我们再执行以下编译tsc
会有报错,先不看报错,看dist
文件目录下只有一个app.js
设置**outFile**
后,所有的全局作用域中的代码会合并到同一个文件中
如果将ts中的模块化整上,你就整不上了
Only 'amd' and 'system' modules are supported alongside --outFile.
意思是:如果你想要把多个模块给它合并成一个文件,你必须使用模块化规范,必须是amd
或者system
{
...
"compilerOptions": {
"target": "ES6",
"module": "system",
"outDir": "./dist",
"outFile": "./dist/app.js"
}
}
我们在这里用的不多。因为这个不灵活,实际上这种应该结合打包工具去使用的
allowJs
allow:允许,js:js
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"outDir": "./dist",
//是否对我们js文件进行编译,默认是false
"allowJs": false
}
}
在我们src
目录下创建hello.js
执行编译,发现没有进dist
目录下
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"outDir": "./dist",
//是否对我们js文件进行编译,默认是false
"allowJs": true
}
}
checkJs
是否检查js代码的语法是否符合语法规范,默认是false
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
"outDir": "./dist",
"allowJs": true,
"checkJs": false
}
}
removeComments
是否移除注释
noEmit
不生成编译后的文件
有些时候,就是我不想ts的编译功能,只想用ts去检查一下语法
其实使用几率不是那么大
onEmitOnError
也是不生成js代码,但是这个有一个前提条件,就是当有错误的时候,不生成编译后的文件
语法检查的
alwaysStrict
严格模式的语法
怎么开启严格模式
js文件为例:手动加上一个字符串
"use strict"
let b = 20;
let c = 'hello';
这就表示开启了我们的严格模式
在ts文件下进行编译的时候,是不会带严格模式,但凡,我们需要在ts里面使用严格模式就会用到alwaysStrict
**alwaysStrict**
:用来设置编译后的文件是否使用严格模式,默认是false
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
// "lib": ["ES6","DOM"],
"outDir": "./dist",
// "outFile": "./dist/app.js"
"alwaysStrict": true
}
}
就会默认在一个严格模式下了
noImplicitAny
Any我们都知道是ts中的一个类型,当我们整一个变量不指定类型,这个变量的默认类型就是any
function fun(a,b){
return a+b
}
any一旦设置实际上就关闭了我们ts对所有类型的检查,所以我们是不推荐使用any的,但是我们使用了any,ts中没有任何的报错,这时候帮我们检查是否有隐式的any的时候,我们就可以使用noImplicitAny
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
// "lib": ["ES6","DOM"],
"outDir": "./dist",
// "outFile": "./dist/app.js"
"noImplicitAny": true
}
}
上面隐式的any就会报错
**noImplicitAny**
:不允许隐式的any
noImplicitThis
与**noImplicitAny**
类似
不允许不明确类型的this
function fun2(){
alert(this)
}
你不确定this
是什么;你用到的方法它没有,那这个时候,我们就希望ts编译器它可以把这个错误和隐患给我们检查出来
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
// "lib": ["ES6","DOM"],
"outDir": "./dist",
// "outFile": "./dist/app.js"
"noImplicitAny": true,
"noImplicitThis": true
}
}
这时this就报错了
说白了我不明确这个this到底是什么
怎么解决这个问题
function fun2(this:any){
alert(this)
}
或是知道是一个window:
function fun2(this:Window){
alert(this)
}
不允许不明确类型的this
strictNullChecks
严格的检查空值
let box1 = document.getElementById('box1');
box1.addEventListener('click',function(){
alert('hello');
})
这是js中很简单的点击事件,但是,我确定这个box1
这个元素浏览器里有吗?
可能box1
不存在,不存在的话,就是null,可能会报错。但是ts编译器没有给我检查出来这个问题,就是因为strictNullChecks
没有设置为true
提醒我
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
// "lib": ["ES6","DOM"],
"outDir": "./dist",
// "outFile": "./dist/app.js"
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true
}
}
就会给你提示:
box1对象可能为null
怎么解决这个问题?
可以做一个判断:
let box1 = document.getElementById('box1');
if(box1 != null){
box1.addEventListener('click',function(){
alert('hello');
})
}
或者
let box1 = document.getElementById('box1');
box1?.addEventListener('click',function(){
alert('hello');
})
strict
所有严格检查的总开关
这个如果为true,以上几个严格语法检查全部打开
也就是:
{
...
"compilerOptions": {
"target": "ES6",
"module": "ES6",
// "lib": ["ES6","DOM"],
"outDir": "./dist",
// "outFile": "./dist/app.js"
"strict": true,
/*
strict为true,以下的几个严格检查都可以省略不写
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true
*/
}
}
一般开发建议,改为true
其实配置还有很多,一边学一边用