TypeScript——编译器和编译选项
编译器和编译选项1、编译器1.1、安装编译器1.1.1、--help、--all1.1.2、--version2、编译程序2.1、编译单个文件2.2、编译多个文件2.3、--watch和-w2.4、--presserveWatchOutput2、编译选项2.1、编译选项风格2.2、使用编译选项2.3、严格类型检查2.3.1、--strict2.3.2、--nolmplicitAny2.3.3、--strictNullChecks2.3.4、--strictFunctionTypes2.3.5、--strictBindCallApply2.3.6、--strictPropertyInitialization2.3.7、--noImplicitThis2.3.8、--alwaysStrict2.4、编译选项列表1、编译器TypeScript编译器是一段JavaScript程序能够对TypeScript代码和JavaScript代码进行静态类型检查并且可以将TypeScript程序编译为可执行的JavaScript程序。TypeScript编译器是自托管编译器[插图]它使用TypeScript语言进行开发。TypeScript编译器程序位于TypeScript语言安装目录下的lib文件夹中。TypeScript编译器对外提供了一个命令行工具用来编译TypeScript程序它就是tsc命令。1.1、安装编译器安装了Node.js之后在命令行窗口中运行下列命令来全局安装TypeScript语言npminstall-gtypescript在不同的操作系统中全局安装的TypeScript会被安装到不同的目录下。例如在Windows系统中TypeScript会被安装到“%AppData%\npm”目录下。1.1.1、–help、–all在成功地安装了TypeScript后我们就可以在命令行上使用tsc命令。按照惯例可以使用“–help”简写为“-h”选项来显示tsc命令的帮助信息。示例如下tsc--help运行该命令将产生类似于如下的输出结果Version3.8.3 Syntax: tsc[options][file...]Examples: tsc hello.ts tsc--outFilefile.js file.ts tsc args.txt tsc--buildtsconfig.json Options: -h,--helpPrint this message. -w,--watchWatch input files....在默认情况下“–help”选项仅会显示基本的帮助信息。我们可以使用额外的“–all”选项来查看完整的帮助信息。示例如下tsc--help--all1.1.2、–version使用“–version”命令行选项能够查看当前安装的编译器版本号。示例如下tsc--versionVersion3.8.32、编译程序2.1、编译单个文件TypeScript编译器最基本的使用方式是编译单个文件。假设当前工程目录结构如下C:\app -- index.ts“index.ts”文件的内容如下functionadd(x:number,y:number):number{returnxy;}在“C:\app”目录下运行tsc命令来编译“index.ts”文件示例如下tsc index.ts默认情况下编译器会在“C:\app”目录下生成编译后的“index.js”文件其内容如下functionadd(x,y){returnxy;}当前工程目录结构如下C:\app |-- index.js -- index.ts如果待编译文件的文件名中带有空白字符如空格那么就需要使用转义符号“\”或者使用单、双引号将文件名包围起来。假设当前工程目录结构如下C:\app -- filename with spaces.ts在“C:\app”目录下运行tsc命令来编译“filename withspaces.ts”文件。示例如下# 使用双引号tscfilename with spaces.ts# 使用单引号tscfilename with spaces.ts# 使用转义符号tsc filename\with\spaces.ts2.2、编译多个文件TypeScript编译器能够同时编译多个文件。我们可以在命令行上逐一列出待编译的文件也可以使用通配符来模糊匹配待编译的文件。假设当前工程目录结构如下C:\app |-- index.ts -- utils.ts在“C:\app”目录下运行tsc命令来编译“index.ts”和“utils.ts”文件。示例如下tsc index.ts utils.ts除此之外还可以使用通配符来匹配待编译的文件支持的通配符包括“*”匹配零个或多个字符但不包含目录分隔符。“?”匹配一个字符但不包含目录分隔符。“**/”匹配任意目录及其子目录。在“C:\app”目录下运行tsc命令并使用通配符来匹配当前目录下的所有TypeScript文件。示例如下tsc *.ts不论使用以上哪种方式来指定待编译的文件编译器都会在“C:\app”目录下生成编译后的“index.js”文件和“utils.js”文件工程目录结构如下C:\app |-- index.js |-- index.ts |-- utils.js -- utils.ts2.3、–watch和-wTypeScript编译器提供了一种特殊的编译模式即观察模式。在观察模式下编译器会监视文件的修改并自动重新编译文件。观察模式通过“–watch”简写为“-w”编译选项来启用。假设当前工程目录结构如下C:\app -- index.ts在“C:\app”目录下运行tsc命令来编译“index.ts”文件并启用观察模式。示例如下tsc index.ts--watch运行tsc命令后编译器会编译“index.ts”文件并进入观察模式。在命令行窗口中能够看到如下输出消息[1:00:00 PM]Starting compilationinwatchmode...[1:00:01 PM]Found0errors. Watchingforfilechanges.这时如果我们修改“index.ts”文件并保存编译器会自动重新编译“index.ts”文件。在命令行窗口中能够看到如下输出消息[1:00:10 PM]File change detected. Starting incremental compilation...[1:00:11 PM]Found0errors. Watchingforfilechanges.编译器在重新编译了“index.ts”文件之后依然会继续监视文件的修改。2.4、–presserveWatchOutput在观察模式下编译器每次编译文件之前都会清空命令行窗口中的历史输出信息。如果我们想保留每一次编译的输出信息则可以使用“–preserveWatchOutput”编译选项。示例如下tsc index.ts--watch--preserveWatchOutput2、编译选项编译选项是传递给编译器程序的参数使用编译选项能够改变编译器的默认行为。在编译程序时编译选项不是必须指定的。本节不会介绍完整的编译选项列表而是会列举出部分常用的编译选项并介绍如何使用它们。2.1、编译选项风格TypeScript编译选项的命名风格包含以下两种长名字风格如“–help”。短名字风格如“-h”。每一个编译选项都有一个长名字但是不一定有短名字。在TypeScript中不论是长名字风格的编译选项还是短名字风格的编译选项均不区分大小写即“–help”“–HELP”“-h”“-H”表示相同的含义。长名字风格的编译选项由两个连字符和一个单词词组构成。提供长名字风格的命令行选项是推荐的做法。它有助于在不同程序之间保持一致的、具有描述性的选项名从而提高开发者的使用体验。短名字风格的编译选项名由单个连字符和单个字母构成。TypeScript编译器仅针对一小部分常用的编译选项提供了短名字。如果一个编译选项具有短名字形式那么该短名字通常为其长名字的首字母例如“–help”编译选项的短名字为“-h”。由于提供了短名字的编译选项数量较少且十分常用因此我们在表中列出了所有支持短名字风格的编译选项。2.2、使用编译选项在运行tsc命令时可以在命令行上指定编译选项。有一些编译选项在使用时不必传入参数只需要写出编译选项名即可例如“–version”。示例如下tsc--version我们也可以使用“–version”编译选项的短名字形式“-v”。示例如下tsc-v实际上每一个编译选项都能够接受一个参数值只不过有一些编译选项具有默认值因此也可以省略传入参数。在给编译选项传入参数时需要将参数写在编译选项名之后并以空格字符分隔。例如“–emitBOM”编译选项接受true或false作为参数值。该编译选项设置了编译器在生成输出文件时是否插入byte order markBOM[插图]。示例如下tsc--emitBOMtrue如果编译选项的参数值是布尔类型并且值为true那么就可以省略传入参数值。因此上例中的命令等同于tsc--emitBOM但如果编译选项的参数值不是布尔类型的true或false那么就不能省略参数值必须在命令行上设置一个参数值。示例如下tsc--targetES5如果想要同时使用多个编译选项那么在编译选项之间使用空格分隔即可。示例如下tsc--version--localezh-CN此例中同时使用了“–version”和“–locale”编译选项。“–locale”编译选项能够设置显示信息时使用的区域和语言它的可选值如下英语en捷克语cs德语de西班牙语es法语fr意大利语it日语ja韩语ko波兰语pl葡萄牙语pt-BR俄语ru土耳其语tr简体中文zh-CN2.3、严格类型检查TypeScript编译器提供了两种类型检查模式即严格类型检查和非严格类型检查。非严格类型检查是默认的类型检查模式该模式下的类型检查比较宽松。在将已有的JavaScript代码迁移到TypeScript时通常会使用这种类型检查模式因为这样做可以让迁移工作更加顺利地进行不至于一时产生过多的错误。在严格类型检查模式下编译器会进行额外的类型检查从而能够更好地保证程序的正确性。严格类型检查功能使用一系列编译选项来开启。在开始一个新的工程时强烈推荐启用所有严格检查编译选项。对于已有的工程则可以逐步启用这些编译选项。因为只有如此才能够最大限度地利用编译器的静态类型检查功能。2.3.1、–strict“–strict”编译选项是所有严格类型检查编译选项的“总开关”。如果启用了“–strict”编译选项那么就相当于同时启用了下列编译选项–noImplicitAny–strictNullChecks–strictFunctionTypes–strictBindCallApply–strictPropertyInitialization–noImplicitThis–alwaysStrict在实际工程中我们可以先启用“–strict”编译选项然后再根据需求禁用不需要的某些严格类型检查编译选项。这样做有一个优点那就是在TypeScript语言发布新版本时可能会引入新的严格类型检查编译选项如果启用了“–strict”编译选项那么就会自动应用新引入的严格类型检查编译选项。“–strict”编译选项既可以在命令行上使用也可以在“tsconfig.json”配置文件中使用。在命令行上使用该编译选项示例如下tsc--strict在“tsconfig.json”配置文件中使用该编译选项示例如下{compilerOptions:{strict:true}}上例的配置等同于如下“tsconfig.json”配置文件{compilerOptions:{noImplicitAny:true,strictNullChecks:true,strictFunctionTypes:true,strictBindCallApply:true,strictPropertyInitialization:true,noImplicitThis:true,alwaysStrict:true}}2.3.2、–nolmplicitAny若一个表达式没有明确的类型注解并且编译器又无法推断出一个具体的类型时那么它将被视为any类型。编译器不会对any类型进行类型检查因此可能存在潜在的错误。例如下例中的函数参数str既没有类型注解也无法推断出具体类型因此它的类型为any类型。不论我们使用哪种类型调用函数f都不会产生编译错误但如果实际参数不是string类型那么在代码运行时会产生错误。示例如下/** * --noImplicitAnyfalse */functionf(str){// ~~~// 类型为anyconsole.log(str.substring(3));}f(42);// 运行时错误如果启用了“–noImplicitAny”编译选项那么当表达式的推断类型为any类型时将产生编译错误。因此上例中的代码在启用了“–noImplicitAny”编译选项的情况下将产生编译错误。示例如下/** * --noImplicitAnytrue */functionf(str){// ~~~// 编译错误参数 str 隐式地成为 any 类型console.log(str.substring(3));}f(42);2.3.3、–strictNullChecks若没有启用“–strictNullChecks”编译选项编译器在类型检查时将忽略undefined值和null值。示例如下/** * --strictNullChecksfalse */functionf(str:string){console.log(str.substring(3));}// 以下均没有编译错误但在运行时产生错误f(undefined);f(null);此例中函数f期望传入string类型的参数并且在传入undefined值和null值时编译器没有产生错误。因为在没有启用“–strictNullChecks”编译选项的情况下当编译器遇到undefined值和null值时会跳过类型检查。而实际上此例中的代码在运行时会产生错误因为在undefined值或null值上调用方法将抛出“TypeError”异常。如果启用了“–strictNullChecks”编译选项那么undefined值只能赋值给undefined类型顶端类型、void类型除外null值也只能赋值给null类型顶端类型除外两者都明确地拥有了各自的类型。因此上例中的代码在该编译选项下会产生编译错误。示例如下/** * --strictNullCheckstrue */functionf(str:string){console.log(str.substring(3));}f(undefined);//~~~~~~~~~//编译错误undefined 不能赋值给 string 类型的参数f(null);//~~~~//编译错误null 不能赋值给 string 类型的参数2.3.4、–strictFunctionTypes该编译选项用于配置编译器对函数类型的类型检查规则。如果启用了“–strictFunctionTypes”编译选项那么函数参数类型与函数类型之间是逆变关系。如果禁用了“–strictFunctionTypes”编译选项那么函数参数类型与函数类型之间是相对宽松的双变关系。不论是否启用了“–strictFunctionTypes”编译选项函数返回值类型与函数类型之间始终是协变关系。2.3.5、–strictBindCallApply“Function.prototype.call”“Function.prototype.bind”“Function.prototype.apply”是JavaScript语言中函数对象上的内置方法。这三个方法都能够绑定函数调用时的this值。例如下例中的6、7、8行将调用函数f时的this值设置成了对象“{ name: ‘ts’ }”functionf(this:{name:string},x:number,y:number){console.log(this.name);console.log(xy);}f.apply({name:ts},[1,2]);f.call({name:ts},1,2);f.bind({name:ts})(1,2);如果没有启用“–strictBindCallApply”编译选项那么编译器不会对以上三个内置方法进行类型检查。虽然函数声明f中定义了this的类型以及参数x和y的类型但是传入任何类型的实际参数都不会产生编译错误。示例如下/** * --strictBindCallApplyfalse */functionf(this:{name:string},x:number,y:number){console.log(this.name);console.log(xy);}// 下列语句均没有编译错误f.apply({},[param]);f.call({},param);f.bind({})(param);如果启用了“–strictBindCallApply”编译选项那么编译器将对以上三个内置方法的this类型以及参数类型进行严格的类型检查。示例如下/** * --strictBindCallApplytrue */functionf(this:Window,str:string){returnthis.alert(str);}f.call(document,foo);// ~~~~~~~~// 编译错误document 类型的值不能赋值给 window 类型的参数f.call(window,false);// ~~~~~// 编译错误false 类型的值不能赋值给 string 类型的参数f.apply(document,[foo]);// ~~~~~~~~// 编译错误document 类型的值不能赋值给 window 类型的参数f.apply(window,[false]);// ~~~~~// 编译错误false 类型的值不能赋值给 string 类型的参数f.bind(document);// ~~~~~~~~// 编译错误document 类型的值不能赋值给 window 类型的参数// 正确的用法f.call(window,foo);f.apply(window,[foo]);f.bind(window);2.3.6、–strictPropertyInitialization该编译选项用于配置编译器对类属性的初始化检查。如果启用了“–strictPropertyInitialization”编译选项那么当类的属性没有进行初始化时将产生编译错误。类的属性既可以在声明时直接初始化例如下例中的属性x也可以在构造函数中初始化例如下例中的属性y。如果一个属性没有使用这两种方式之一进行初始化那么会产生编译错误例如下例中的属性z。示例如下/** * -- strictPropertyInitializationtrue */classPoint{x:number0;y:number;z:number;// 编译错误属性 z 没有初始值也没有在构造函数中初始化constructor(){this.y0;}}若没有启用“–strictPropertyInitialization”编译选项那么上例中的代码不会产生编译错误。也就是说允许未初始化的属性z存在。使用该编译选项时需要注意一种特殊情况有时候我们会在构造函数中调用其他方法来初始化类的属性而不是在构造函数中直接进行初始化。目前编译器无法识别出这种情况依旧会认为类的属性没有被初始化进而产生编译错误。我们可以使用“!”类型断言来解决这个问题示例如下/** * -- strictPropertyInitializationtrue */classPoint{x:number;// 编译错误属性 x 没有初始值也没有在构造函数中初始化y!:number;// 正确constructor(){this.initX();this.initY();}privateinitX(){this.x0;}privateinitY(){this.y0;}}2.3.7、–noImplicitThis与“–noImplicitAny”编译选项类似在启用了“–noImplicitThis”编译选项时如果程序中的this值隐式地获得了any类型那么将产生编译错误。示例如下/** * -- noImplicitThistrue */classRectangle{width:number;height:number;constructor(width:number,height:number){this.widthwidth;this.heightheight;}getAreaFunctionWrong(){returnfunction(){returnthis.width*this.height;// ~~~~ ~~~~// 编译错误this 隐式地获得了 any 类型// 因为不存在类型注解};}getAreaFunctionCorrect(){returnfunction(this:Rectangle){returnthis.width*this.height;};}}2.3.8、–alwaysStrictECMAScript 5引入了一个称为严格模式[插图]的新特性。在全局JavaScript代码或函数代码的开始处添加““usestrict””指令就能够启用JavaScript严格模式。在模块和类中则会始终启用JavaScript严格模式。注意JavaScript严格模式不是本节所讲的TypeScript严格类型检查模式。在JavaScript严格模式下JavaScript有着更加严格的语法要求和一些新的语义。例如implements、interface、let、package、private、protected、public、static和yield都成了保留关键字在函数的形式参数列表中不允许出现同名的形式参数等。若启用了“–alwaysStrict”编译选项则编译器总是以JavaScript严格模式的要求来检查代码并且在编译生成JavaScript代码时会在代码的开始位置添加““use strict””指令。示例如下/** * --alwaysStricttrue */functionouter(){if(true){functioninner(){// ~~~~~// 编译错误当编译目标为ES3或ES5时// 在严格模式下的语句块中不允许使用函数声明}}}此例中只有在启用了“–alwaysStrict”编译选项时第6行代码才会产生编译错误。因为在JavaScript严格模式下语句块中不允许出现函数声明。2.4、编译选项列表随着TypeScript版本的更新提供的编译选项列表也会有所变化。例如一些编译选项会被废弃也会有一些新加入的编译选项。推荐读者到TypeScript官方网站上的“Compiler Options”页面[插图]中了解最新的编译选项列表。官方网站的Compiler Options页面地址https://www.typescriptlang.org/docs/handbook/compiler-options.html。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2463301.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!