你能描述一下TypeScript语言是什么吗?
JavaScript或可用库不能做什么,这会让我有理由考虑它?
你能描述一下TypeScript语言是什么吗?
JavaScript或可用库不能做什么,这会让我有理由考虑它?
当前回答
“TypeScript基础知识”——Dan Wahlin和John Papa的Pluralsight视频课程非常不错,目前(2016年3月25日)进行了更新,以反映TypeScript 1.8,TypeScript简介。
对我来说,除了智能感知的良好可能性之外,真正好的特性是类、接口、模块、易于实现AMD,以及在使用IE调用时使用Visual Studio Typescript调试器的可能性。
总而言之:如果按预期使用,Typescript可以使JavaScript编程更可靠、更容易。与完整的SDLC相比,它可以显著提高JavaScript程序员的生产力。
其他回答
“TypeScript基础知识”——Dan Wahlin和John Papa的Pluralsight视频课程非常不错,目前(2016年3月25日)进行了更新,以反映TypeScript 1.8,TypeScript简介。
对我来说,除了智能感知的良好可能性之外,真正好的特性是类、接口、模块、易于实现AMD,以及在使用IE调用时使用Visual Studio Typescript调试器的可能性。
总而言之:如果按预期使用,Typescript可以使JavaScript编程更可靠、更容易。与完整的SDLC相比,它可以显著提高JavaScript程序员的生产力。
TypeScript与JavaScript的关系
TypeScript是JavaScript的一个类型化超集,可编译为纯文本JavaScript-typescriptlang.org。
JavaScript是一种编程语言,由ECMA的技术委员会39开发,该委员会由许多不同的利益相关者组成。TC39是一个由内部标准组织ECMA主持的委员会。JavaScript由许多不同的供应商(如谷歌、微软、甲骨文等)提供了许多不同的实现。JavaScript的目标是成为网络的通用语言。
TypeScript是JavaScript语言的超集,它有一个开源编译器,主要由一个供应商开发:Microsoft。TypeScript的目标是帮助通过类型系统及早发现错误,并使JavaScript开发更高效。
基本上,TypeScript通过三种方式实现其目标:
支持现代JavaScript功能——JavaScript语言(而不是运行时)通过ECMAScript标准标准化。并非所有浏览器和JavaScript运行时都支持所有ECMAScript标准的所有功能(请参阅本概述)。TypeScript允许使用许多最新的ECMAScript功能,并将它们转换为您选择的较旧的ECMASript目标(请参阅--target编译器选项下的编译目标列表)。这意味着您可以安全地使用新功能,如模块、lambda函数、类、扩展运算符和析构函数,同时保持与旧浏览器和JavaScript运行时的向后兼容。高级类型系统-类型支持不是ECMAScript标准的一部分,可能永远不会因为JavaScript的解释性质而不是编译性质。TypeScript的类型系统非常丰富,包括:接口、枚举、混合类型、泛型、联合/交叉类型、访问修饰符等等。TypeScript的官方网站概述了这些功能。Typescript的类型系统与大多数其他类型语言不相上下,在某些情况下可以说更强大。开发人员工具支持-TypeScript的编译器可以作为后台进程运行,以支持增量编译和IDE集成,这样您就可以更轻松地导航、识别问题、检查可能性和重构代码库。
TypeScript与其他JavaScript目标语言的关系
与其他编译为JavaScript的语言相比,TypeScript具有独特的理念。JavaScript代码是有效的TypeScript代码;TypeScript是JavaScript的超集。您几乎可以将.js文件重命名为.ts文件并开始使用TypeScript(请参阅下面的“JavaScript互操作性”)。TypeScript文件被编译成可读的JavaScript,这样就可以迁移回去,而且理解编译的TypeScript一点都不困难。TypeScript建立在JavaScript成功的基础上,同时改进其弱点。
一方面,您有未来证明工具,可以采用现代ECMAScript标准,并将其编译为较旧的JavaScript版本,其中最流行的是Babel。另一方面,您的语言可能与以JavaScript为目标的JavaScript完全不同,如CoffeeScript、Clojure、Dart、Elm、Haxe、Scala.js等,还有一大堆其他语言(请参阅此列表)。尽管这些语言可能比JavaScript的未来更好,但它们面临着更大的风险,即无法找到足够的应用来保证其未来。对于这些语言中的一些语言,您可能也很难找到经验丰富的开发人员,尽管您会发现他们往往更热情。与JavaScript的互操作性也可能涉及更多,因为它们与JavaScript的实际情况相去甚远。
TypeScript介于这两个极端之间,从而平衡了风险。从任何标准来看,TypeScript都不是一个冒险的选择。如果您熟悉JavaScript,则只需很少的努力就可以习惯,因为它不是一种完全不同的语言,具有出色的JavaScript互操作性支持,并且最近已被大量采用。
可选的静态类型和类型推断
JavaScript是动态类型的。这意味着JavaScript不知道变量是什么类型,直到它在运行时被实际实例化。这也意味着可能为时已晚。TypeScript为JavaScript添加了类型支持,并在编译到JavaScript时捕获类型错误。如果你打对了牌(键入代码的严格程度或键入代码的程度取决于你),由错误假设某个变量属于某一类型而导致的错误可以被彻底根除。
通过使用类型推断,TypeScript使键入变得更加简单,而且显式性大大降低。例如:TypeScript中的var x=“hello”与var x:string=“hello“相同。该类型只是从其使用中推断出来的。即使您没有显式地键入类型,它们仍然可以帮助您避免执行某些可能导致运行时错误的操作。
默认情况下,可以选择键入TypeScript。例如,函数divideByTwo(x){return x/2}是TypeScript中的一个有效函数,可以使用任何类型的参数调用,即使使用字符串调用它显然会导致运行时错误。就像你习惯于JavaScript一样。这是有效的,因为当没有显式分配类型并且无法推断类型时,就像在divideByTwo示例中一样,TypeScript将隐式分配类型any。这意味着divideByTwo函数的类型签名自动变为函数divideByTwo(x:any):any。有一个编译器标志禁止这种行为:--noImplicitAny。启用此标志可以提供更高的安全性,但也意味着您必须执行更多的键入操作。
类型具有与其相关的成本。首先,有一个学习曲线,其次,当然,使用适当的严格类型设置代码库也会花费更多的时间。根据我的经验,这些成本完全值得你与他人分享任何严肃的代码库。Github中对编程语言和代码质量的大规模研究表明,“一般来说,静态类型的语言比动态类型更不容易出现缺陷,在这方面,强类型比弱类型要好”。
有趣的是,这篇论文发现TypeScript比JavaScript更容易出错:
对于那些具有正系数的人,我们可以预期语言同样,与更多的缺陷修复相关。这些语言包括C、C++、JavaScript、Objective-C、Php和蟒蛇Clojure、Haskell、Ruby、Scala和TypeScript语言,所有这些都有负系数,这意味着这些语言更少可能会导致缺陷修复提交。
增强的IDE支持
TypeScript的开发经验比JavaScript有很大的改进。TypeScript编译器实时通知IDE其丰富的类型信息。这有两个主要优点。例如,使用TypeScript,您可以安全地在整个代码库中进行重命名等重构。通过代码完成,您可以获得关于库可能提供的任何函数的内联帮助。不再需要记住它们或在在线参考资料中查找它们。编译错误直接在IDE中报告,并在您忙于编码时显示一条红色的曲线。总而言之,与使用JavaScript相比,这可以显著提高生产率。人们可以花费更多的时间进行编码,而花费更少的时间进行调试。
有很多IDE都非常支持TypeScript,比如VisualStudioCode、WebStorm、Atom和Sublime。
严格的空检查
表单的运行时错误无法读取未定义或未定义的属性“x”。这不是一个函数,通常是由JavaScript代码中的错误引起的。现成的TypeScript已经降低了发生此类错误的可能性,因为不能使用TypeScript编译器不知道的变量(除了任何类型化变量的财产)。但仍有可能错误地使用设置为undefined的变量。然而,使用2.0版本的TypeScript,您可以通过使用不可为null的类型一起消除这些类型的错误。其工作原理如下:
如果启用了严格的空检查(--strictNullChecks编译器标志),TypeScript编译器将不允许将undefined赋值给变量,除非您明确声明变量为可空类型。例如,让x:number=undefined将导致编译错误。这完全符合类型理论,因为undefined不是一个数字。可以将x定义为数字的和类型,而undefined可以纠正这一点:让x:number|undefined=undefineed。
一旦一个类型已知为可为null,意味着它的类型也可以为null或undefined,TypeScript编译器就可以通过基于控制流的类型分析来确定代码是否可以安全地使用变量。换句话说,当您通过例如if语句检查变量是否未定义时,TypeScript编译器将推断代码控制流的该分支中的类型不再可为null,因此可以安全使用。下面是一个简单的例子:
let x: number | undefined;
if (x !== undefined) x += 1; // this line will compile, because x is checked.
x += 1; // this line will fail compilation, because x might be undefined.
在构建过程中,TypeScript的2016年会议联合设计师Anders Hejlsberg对该功能进行了详细的解释和演示:视频(从44:30到56:30)。
汇编
要使用TypeScript,您需要一个编译过程来编译为JavaScript代码。构建过程通常只需要几秒钟,这当然取决于项目的大小。TypeScript编译器支持增量编译(--watch编译器标志),以便可以更快地编译所有后续更改。
TypeScript编译器可以在生成的.js文件中内联源映射信息,也可以创建单独的.map文件。调试工具(如Chrome DevTools和其他IDE)可以使用源映射信息,将JavaScript中的行与TypeScript中生成行的行关联起来。这使得您可以在运行时直接在TypeScript代码上设置断点和检查变量。源映射信息工作得很好,早在TypeScript之前就有了,但调试TypeScript通常不如直接使用JavaScript时好。以this关键字为例。由于自ES2015以来围绕闭包的这个关键字的语义发生了变化,这实际上可能在运行时作为一个名为_this的变量存在(参见这个答案)。在调试过程中,这可能会让您感到困惑,但如果您了解或检查JavaScript代码,这通常不是问题。应该指出的是,巴别尔也面临着同样的问题。
TypeScript编译器还可以做一些其他的技巧,比如基于修饰符生成拦截代码、为不同的模块系统生成模块加载代码以及解析JSX。然而,除了Typescript编译器之外,您可能还需要一个构建工具。例如,如果要压缩代码,则必须在构建过程中添加其他工具。
Webpack、Gulp、Grunt和几乎任何其他JavaScript构建工具都可以使用TypeScript编译插件。TypeScript文档中有一节关于与构建工具集成,涵盖了所有这些工具。如果您需要更多的构建时间检查,也可以使用linter。还有大量的种子项目可以让你开始使用TypeScript,并结合一系列其他技术,如Angular 2、React、Ember、SystemJS、Webpack、Gulp等。
JavaScript互操作性
由于TypeScript与JavaScript密切相关,因此它具有很强的互操作性,但在TypeScript中使用JavaScript库需要一些额外的工作。需要TypeScript定义,以便TypeScript编译器了解像_.groupBy或angular.copy或$.fadeOut这样的函数调用实际上不是非法语句。这些函数的定义放在.d.ts文件中。
定义可以采取的最简单形式是允许以任何方式使用标识符。例如,当使用Lodash时,一个单行定义文件声明var_:any将允许您对_调用任何所需的函数,但当然,您也可能会犯错误:_.foobar()将是合法的TypeScript调用,但在运行时是非法的调用。如果你想要正确的类型支持和代码完成,你的定义文件需要更精确(参见lodash定义的示例)。
预先打包了自己的类型定义的Npm模块会被TypeScript编译器自动理解(请参阅文档)。对于几乎所有其他不包含自己定义的半流行JavaScript库,已经有人通过另一个npm模块提供了类型定义。这些模块前缀为“@types/”,来自名为DefinelyTyped的Github存储库。
有一个警告:类型定义必须与运行时使用的库的版本相匹配。如果没有,TypeScript可能会禁止您调用函数或取消引用存在的变量,或者允许您调用不存在的函数或取消对不存在的变量的引用,这仅仅是因为类型与编译时的运行时不匹配。因此,请确保为正在使用的库的正确版本加载正确版本的类型定义。
老实说,这有点麻烦,这可能是你不选择TypeScript的原因之一,而是选择像Babel这样完全不必获取类型定义的东西。另一方面,如果你知道你在做什么,你可以很容易地克服任何由不正确或缺少定义文件引起的问题。
从JavaScript转换为TypeScript
任何.js文件都可以重命名为.ts文件,并通过TypeScript编译器运行,以获得与输出语法相同的JavaScript代码(如果一开始语法正确)。即使TypeScript编译器出现编译错误,它仍然会生成.js文件。它甚至可以接受.js文件作为带有--allowJs标志的输入。这允许您立即开始使用TypeScript。不幸的是,编译错误很可能在开始时发生。需要记住的是,这些错误不会像其他编译器那样显示停止错误。
在将JavaScript项目转换为TypeScript项目时,一开始就会出现编译错误,这是TypeScript的本质所无法避免的。TypeScript检查所有代码的有效性,因此它需要了解所使用的所有函数和变量。因此,所有类型的定义都需要到位,否则势必会发生编译错误。如上一章所述,对于几乎任何JavaScript框架,都有.d.ts文件,可以通过安装DefinelyTyped包轻松获取。然而,这可能是因为您使用了一些晦涩难懂的库,其中没有TypeScript定义,或者您对一些JavaScript原语进行了聚合填充。在这种情况下,必须为这些位提供类型定义,以使编译错误消失。只需创建一个.d.ts文件并将其包含在tsconfig.json的文件数组中,以便TypeScript编译器始终考虑它。在其中,将TypeScript不知道的那些位声明为any类型。一旦您消除了所有错误,就可以根据您的需要逐步将打字引入这些部分。
为了将TypeScript导入到生成管道中,还需要进行一些(重新)配置生成管道的工作。正如编译一章中提到的,有很多好的资源,我鼓励您寻找使用您想要使用的工具组合的种子项目。
最大的障碍是学习曲线。我鼓励你一开始就玩一个小项目。看看它是如何工作的,它是如何构建的,它使用了哪些文件,它是怎样配置的,它在IDE中是如何运行的,它的结构是怎样的,它所使用的工具等等。当你知道自己在做什么时,将一个大型JavaScript代码库转换为TypeScript是可行的。阅读本博客,例如在72小时内将600k行转换为打字脚本)。在跳之前,确保你对语言有很好的掌握。
采用
TypeScript是开源的(Apache 2许可,参见GitHub),并由Microsoft支持。C#的首席架构师Anders Hejlsberg是该项目的领导者。这是一个非常活跃的项目;TypeScript团队在过去几年中发布了许多新功能,许多很棒的功能仍在计划中(参见路线图)。
关于收养和普及的一些事实:
在2017年StackOverflow开发者调查中,TypeScript是最受欢迎的JavaScript转译器(总体排名第9),并在最受欢迎编程语言类别中获得第三名。在2018年js状态调查中,TypeScript被宣布为JavaScript风格类别的两大赢家之一(ES6是另一个)。在2019年StackOverflow开发者调查中,TypeScript在专业开发者中最受欢迎的语言中排名第9,超过了C和C++。它再次在最受喜爱的语言中排名第三。在2020年StackOverflow开发者调查中,TypeScript是第二受欢迎的技术。
TypeScript的作用类似于less或sass对CSS的作用。它们是它的超级集合,这意味着您编写的每个JS代码都是有效的TypeScript代码。此外,您还可以使用它添加到语言中的其他好处,并且转译的代码将是有效的js。您甚至可以设置想要生成代码的JS版本。
目前TypeScript是ES2015的超级集合,因此开始学习新的js特性并将其转换为项目所需的标准可能是一个不错的选择。
所有浏览器都支持并预编译的Ecma脚本5(ES5)。ES6/ES2015和ES/2016今年发生了很多变化,所以要弹出这些变化,需要注意的是,TypeScript。
•TypeScript是Types->意味着我们必须定义每个属性和方法的数据类型。如果你知道C#,那么Typescript很容易理解。
•TypeScript的一大优势是,我们在投入生产之前及早发现与类型相关的问题。如果存在任何类型不匹配,这允许单元测试失败。
我最初是在TypeScript还在的时候写下这个答案的加热印刷机。五年后,这是一个不错的概述,但请看在下面Lodewijk的回答中了解更多深度
1000英尺视图。。。
TypeScript是JavaScript的超集,主要提供可选的静态类型、类和接口。最大的好处之一是使IDE能够在键入代码时提供更丰富的环境来发现常见错误。
要了解我的意思,请观看微软关于该语言的介绍视频。
对于大型JavaScript项目,采用TypeScript可能会产生更健壮的软件,同时仍然可以在常规JavaScript应用程序运行的地方部署。
它是开源的,但如果使用受支持的IDE,则只能在键入时获得智能感知。最初,这只是微软的Visual Studio(在Miguel de Icaza的博客文章中也有提到)。如今,其他IDE也提供TypeScript支持。
还有其他类似的技术吗?
有CoffeeScript,但它确实有不同的用途。IMHO,CoffeeScript为人类提供了可读性,但TypeScript也通过其可选的静态类型为工具提供了深度可读性(请参阅最近的博客文章以获得更多评论)。还有Dart,但它完全可以替代JavaScript(尽管它可以生成JavaScript代码)
实例
例如,这里有一些TypeScript(您可以在TypeScript游乐场中使用它)
class Greeter {
greeting: string;
constructor (message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
下面是它将生成的JavaScript
var Greeter = (function () {
function Greeter(message) {
this.greeting = message;
}
Greeter.prototype.greet = function () {
return "Hello, " + this.greeting;
};
return Greeter;
})();
注意TypeScript如何定义成员变量和类方法参数的类型。这在转换为JavaScript时会被删除,但IDE和编译器会使用它来发现错误,比如将数字类型传递给构造函数。
它还能够推断未显式声明的类型,例如,它将确定greet()方法返回字符串。
调试TypeScript
许多浏览器和IDE通过sourcemap提供直接调试支持。有关详细信息,请参阅此堆栈溢出问题:使用Visual Studio调试TypeScript代码
想了解更多吗?
我最初写这个答案的时候,TypeScript还没有出版。查看Lodewijk对这个问题的回答,了解更多最新信息。