什么是TypeScript,为什么我会用它来代替JavaScript?

你能描述一下TypeScript语言吗?

JavaScript或者可用的库不能做什么,这会让我有理由去考虑它?

1000英尺的看法…

TypeScript是JavaScript的超集,主要提供可选的静态types,类和接口。 其中一个很大的好处是可以使IDE在键入代码时提供更丰富的环境来查找常见错误。

要了解我的意思,请观看Microsoft介绍的语言video 。

对于一个大的JavaScript项目,采用TypeScript可能会产生更强大的软件,同时仍然可以在常规的JavaScript应用程序运行的地方部署。

它是开源的,但是如果您使用受支持的IDE,则只需键入智能感知。 最初,这只是微软的Visual Studio(也在Miguel de Icaza的博客中提到)。 现在, 其他IDE也提供了TypeScript支持 。

还有其他的技术吗?

有CoffeeScript ,但确实有不同的用途。 恕我直言,CoffeeScript为人类提供了可读性,但是TypeScript通过其可选的静态types提供了深度的工具可读性(请参阅最近的博客文章,以获得更多的批评)。 也有飞镖,但这是一个完整的替代JavaScript(虽然它可以产生JavaScript代码 )

作为一个例子,下面是一些TypeScript(你可以在TypeScript Playground中玩这个)

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定义了成员variables和类方法参数的types。 这在转换为JavaScript时被删除,但被IDE和编译器用来发现错误,例如将数字types传递给构造函数。

它也能够推断未明确声明的types,例如,它将确定greet()方法返回一个string。

debugging打字稿

许多浏览器和IDE通过源代码提供直接的debugging支持。 有关更多详细信息,请参阅此堆栈溢出问题: 使用Visual StudiodebuggingTypeScript代码

想知道更多?

我最初编写这个答案时,Typescript仍然热门新闻。 看看Lodewijk对这个问题的回答 ,了解一些更多的细节。

虽然被接受的答案是好的,但是我觉得在这一点上确实没有TypeScript正义。 现在不是早期了。 现在TypeScript正在用TypeScript编写几个stream行的框架,现在发现更多的采用。 现在你应该selectTypeScript而不是JavaScript。

与JavaScript的关系

JavaScript是通过ECMAScript标准进行标准化的。 并非所有正在使用的浏览器都支持更新的ECMAScript标准的所有function(请参阅此表格 )。 TypeScript支持新的ECMAScript标准,并将它们编译为您所select的(较旧的)ECMAScript目标(当前目标为3,5和6 [也就是2015])。 这意味着您可以使用ES2015及更高版本的function,比如今天的模块,lambda函数,类,扩展运算符,解构。 它还增加了当然的types支持,这不是任何ECMAScript标准的一部分,并且可能永远不会由于解释性而不是JavaScript的编译本质。 TypeScript的types系统相对丰富,包括:接口,枚举,混合types,generics,联合和交集types,访问修饰符等等。 TypeScript的官方网站给出了这些function的概述。

与其他JavaScript定位语言的关系

与编译成JavaScript的其他语言相比,TypeScript具有独特的理念。 JavaScript代码是有效的TypeScript代码; TypeScript是JavaScript的超集。 几乎可以将.js文件重命名为.ts文件,并开始使用TypeScript。 TypeScript文件被编译为可读的JavaScript,因此可以回迁,理解已编译的TypeScript并不难。 通过这种方式,TypeScriptbuild立在JavaScript的成功之上,同时改进了其弱点。

一方面,你有未来的validation工具,采用现代的ECMAScript标准,并将其编译成旧版本的JavaScript,Babel是最受欢迎的。 另一方面,您的语言可能完全不同于JavaScript,如Coffeescript,Clojure,Dart,Elm,Haxe,ScalaJs以及更多的整个主机(请参阅此列表 )。 这些语言虽然可能比JavaScript的未来可能更好,但更有可能没有find足够的采用来保证它们的未来。 对于这些语言中的某些语言,您可能也会遇到更多的困难,尽pipe您会发现这些语言通常会更加热情。 使用JavaScript进行互操作也可能会涉及更多,因为它们远离JavaScript的实际内容。

TypeScript坐在这两个极端之间,从而平衡风险。 TypeScript不是任何标准的风险select。 如果您熟悉JavaScript,只需花费很less的精力,因为它不是一种完全不同的语言,具有出色的JavaScript互操作性支持,并且近来已经被大量采用。

可选静态types和types推断

JavaScript是dynamicinput的。 这意味着JavaScript不知道什么types的variables,直到它实际上在运行时实例化。 这也意味着它可能为时已晚。 TypeScript为JavaScript添加了types支持。 错误地假设某些variables是某种types的错误,如果你正确地玩牌,可以彻底根除; 你input你的代码有多严格,或者你input你的代码完全取决于你。

TypeScript通过types推断的使用使input变得更简单,而且更加简单。 例如:TypeScript中的var x = "hello"var x : string = "hello" 。 这种types只是从它的使用推断。 即使你没有明确地键入types,他们仍然在那里,以避免做一些事情,否则会导致运行时错误。

TypeScript默认是可选的。 例如function divideByTwo(x) { return x / 2 }是TypeScript中的一个有效函数,可以用任何types的参数调用,即使用string调用它也会导致运行时错误。 就像你习惯在JavaScript中一样。 这是有效的,因为当没有明确指定types并且无法推断types时(如divideByTwo示例),TypeScript将隐式指定typesany 。 这意味着divideByTwo函数的types签名会自动变为function divideByTwo(x : any) : any 。 有一个编译器标志来禁止这种行为:– --noImplicitAny 。 启用此标志可以提高您的安全性,但也意味着您需要进行更多的input。

types与他们有关联的成本。 首先有一条学习曲线,其次,当然,使用适当的严格打字也需要花费更多的时间来设置代码库。 根据我的经验,这些代价是完全值得的任何严重的代码库,你与他人分享。 在Github上编程语言和代码质量的大规模研究表明, “静态types语言通常比dynamictypes缺陷容易,在同样的方面,强types优于弱types。

有趣的是,这个非常相同的文章发现,TypeScript不像JavaScript那么容易出错:

对于那些系数为正的人,我们可以预料,语言与其他条件相关联的是更多的缺陷修复。 这些语言包括C,C ++, JavaScript ,Objective-C,Php和Python。 Clojure,Haskell,Ruby,Scala和TypeScript语言都具有负面系数,这意味着这些语言不太可能导致缺陷修改。

增强的IDE支持

使用TypeScript的开发经验是JavaScript的一个很大的改进。 IDE通过TypeScript编译器实时通知其丰富的types信息。 这提供了几个主要的优点。 例如,使用TypeScript,您可以安全地重构整个代码库中的重命名。 通过代码完成,您可以获得图书馆可能提供的任何函数的内联帮助。 没有更多需要记住他们或在网上查阅他们。 编译错误直接在IDE中用红色波浪线报告,而您正忙于编码。 总之,与使用JavaScript相比,这样做可以显着提高工作效率。 人们可以花更多的时间进行编码,debugging时间更less。

有很多种IDE支持TypeScript,比如Visual Studio&VS代码,Atom,Sublime和IntelliJ / WebStorm。

严格的空检查

表单的运行时错误cannot read property 'x' of undefined或者undefined is not a function通常是由JavaScript代码中的错误引起的。 开箱即用的TypeScript已经降低了发生这类错误的可能性,因为不能使用TypeScript编译器不知道的variables( anytypesvariables的属性除外)。 尽pipe错误地使用一个设置为undefined的variables仍然是可能的。 但是,使用TypeScript的2.0版本,您可以通过使用不可空的types来消除这些types的错误。 这工作如下:

如果启用了严格的空检查( --strictNullChecks编译器标志),TypeScript编译器将不允许将undefined分配给variables,除非您明确声明它是可空types的。 例如, let x : number = undefined将导致编译错误。 这完全符合types理论,因为undefined不是一个数字。 可以将x定义为number的和types, undefined可以修正它: let x : number | undefined = undefined let x : number | undefined = undefined 。 简短的符号是let x : number? = undefined let x : number? = undefined

一旦一个types被认为是可空的,意味着它的types也可以是nullundefined ,TypeScript编译器可以通过基于控制stream的types分析来确定你的代码是否可以安全地使用一个variables。 换句话说,当你通过例如if语句检查一个variables是undefinedif ,TypeScript编译器会推断你的代码的控制stream的该分支中的types不再是可空的,因此可以安全地使用。 这是一个简单的例子:

 let x : number?; 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. 

在制作2016年会议期间,TypeScript Anders Hejlsberg的联合devise师对这个function进行了详细的解释和演示: video (从44:30到56:30)。

汇编

要使用TypeScript,您需要一个编译过程来编译为JavaScript代码。 构build过程通常只需要几秒钟,具体取决于项目的大小。 TypeScript编译器支持增量编译( --watch编译器标志),以便所有后续更改可以更快地编译。

TypeScript编译器可以在生成的.js文件中内联源地图信息或创build单独的.map文件。 源地图信息可以被debugging工具使用,例如Chrome DevTools和其他IDE将JavaScript中的行与在TypeScript中生成的行关联起来。 这使您可以在运行时直接在TypeScript代码上设置断点和检查variables。 源地图信息工作得相当不错,大约在TypeScript之前,但是debuggingTypeScript通常不如直接使用JavaScript那么好。 以this关键字为例。 由于自ES2015以来围绕closures的this关键字改变了语义, this在运行时可能实际上是作为_thisvariables存在的(参见本答案 )。 在debugging过程中,这可能会让你感到困惑,但是如果你知道这个问题或者检查JavaScript代码,通常不会有问题。 应该指出,巴别尔遭受同样的问题。

还有一些TypeScript编译器可以做的其他技巧,比如生成基于装饰器的截取代码,为不同的模块系统生成模块加载代码和parsingJSX 。 但是,除了Typescript编译器之外,您可能还需要构build工具。 例如,如果你想压缩你的代码,你将不得不在你的构build过程中添加其他工具来这样做。

Webpack , Gulp , Grunt和几乎所有其他JavaScript构build工具都有TypeScript编译插件。 TypeScript文档有一个关于集成所有构build工具的章节。 如果你想要更多的构build时间检查,还可以使用linter 。 还有大量的种子项目会让你开始使用TypeScript和Angular 2,React,Ember,SystemJs,WebPack,Gulp等其他一些技术。

JavaScript互操作性

由于TypeScript与JavaScript密切相关,因此具有良好的互操作性,但是在TypeScript中使用JavaScript库需要额外的工作。 TypeScript定义是需要的,以便TypeScript编译器明白像_.groupByangular.copy$.fadeOut函数调用实际上不是非法的语句。 这些函数的定义放在.d.ts文件中。

定义最简单的forms是允许以任何方式使用标识符。 例如,当使用Lodash时 ,单行定义文件declare var _ : any将允许你调用_上所需的任何函数,但当然你也可以犯错误: _.foobar()将是一个合法的TypeScript调用,但在运行时当然是非法的调用。 如果你想要正确的types支持和代码完成,你的定义文件需要更加确切(见例子的lodash定义 )。

由TypeScript编译器自动理解由它们自己的types定义预打包的Npm模块 (参见文档 )。 对于几乎所有其他半stream行的JavaScript库,不包括自己的定义(大多数项目在这一点上)有人已经做了一个.d.ts文件。 这些可以通过称为types的命令行工具下载和pipe理。 典型的大部分types定义都来自一个名为DefinitelyTyped的Github仓库,但是也可以通过Github,Npm,Bower等其他来源获得它们。安装Typings之后,你可以在你的项目的命令行上运行typings install lodash目录,你将准备开始使用Lodash。 现在,您的IDE将会在您input_.时确切地告诉您哪些Lodashfunction可用_. 在你的编辑器中。

有一个警告:TypeScript定义必须匹配您在运行时使用的库的版本。 如果他们不这样做,TypeScript可能会禁止您调用函数或取消引用存在的variables,或者允许您调用函数或取消引用不存在的variables。 types使用registry能够提供不同版本的定义。 这是一个相当新的发展,老实说,现在还没有很多不同版本的库可用,所以通常情况下,最好使用库的最新版本,因为定义往往是最新的。

说实话,这有点麻烦,这可能是你不selectTypeScript的原因之一,而是去像Babel这样的东西,根本不需要得到types定义。 另一方面,如果你知道你在做什么,你可以很容易地克服任何types的错误或缺less定义文件的问题。

从JavaScript转换到TypeScript

任何.js文件都可以重命名为.ts ,并通过TypeScript编译器在语法上得到与输出相同的JavaScript代码(如果它在语法上是正确的话)。 即使TypeScript编译器遇到编译错误,它仍然会生成一个.js文件。 它甚至可以接受.js文件作为input与--allowJs标志。 这使您可以马上开始使用TypeScript。 不幸的是编译错误很可能在一开始就发生。 其中一个确实需要记住,这些并不像你可能习惯的其他编译器那样显示停止错误。

在将JavaScript项目转换为TypeScript项目时,开始的编译错误是TypeScript本质所无法避免的。 TypeScript检查所有代码的有效性,因此它需要知道所有使用的函数和variables。 因此types定义需要适用于所有这些types,否则编译错误必然会发生。 正如在上面的章节中提到的,几乎所有的JavaScript框架都有.d.ts文件,可以通过几种types的typings install命令轻松获得.d.ts文件。 但是,可能是因为您使用了一些没有TypeScript定义可用的模糊库,或者您已经填充了一些JavaScript基元。 在这种情况下,您必须为这些位提供types定义,以免编译错误消失。 只需创build一个.d.ts文件并将其包含在tsconfig.json files数组中,以便TypeScript编译器始终考虑它。 在它声明TypeScript不知道的那些typesany 。 一旦你消除了所有的错误,你可以根据你的需要,逐步将这些部分input到这些部分。

一些工作(重新)configuration您的生成pipe道也将需要将TypeScript到生成pipe道。 正如编译章节中提到的那样,我们鼓励您寻找使用您想要工作的工具组合的种子项目。

最大的障碍是学习曲线。 我鼓励你先玩一个小项目。 看看它是如何工作的,如何构build,使用哪些文件,如何configuration,如何在IDE中运行,如何构build,使用哪些工具等。将大型JavaScript代码库转换为TypeScript是非常可行的知道你在做什么,但是当你不这样做的时候可能会感到沮丧。

采用

TypeScript是开源的(Apache 2许可,请参阅github ),并由Microsoft支持。 C#的首席架构师Anders Hejlsberg带领这个项目。 这是一个非常活跃的项目; TypeScript团队在过去几年已经发布了许多新function,并且还有很多很棒的function(参见路线图 )。 这也是目前趋势(见谷歌的趋势 )。 自去年以来,Npm的下载量增加了20倍。 在2016年2月,TypeScript每月有超过一百万次下载( 来源 )。 许多伟大的项目现在使用TypeScript进行编码,最着名的是Angular 2和RxJs。

TypeScript的function类似于CSS或者sass的function。 它们是超集,这意味着你写的每个JS代码都是有效的TypeScript代码。 另外,你可以使用其他的东西,它增加了语言,并且编译的代码将是有效的js。 你甚至可以设置你想要的结果代码的JS版本。

目前TypeScript是ES2015的超级套件,所以开始学习新的js特性并将其转换为您的项目所需的标准可能是一个不错的select。

TypeScript Fundamentals ” – 由Dan WahlinJohn Papa编写的Pluralsightvideo教程是一个非常好的,目前(2016年3月25日)更新,反映TypeScript 1.8,Typescript入门。

对我来说,真正好的function,除了intellisense的好的可能性之外,还有接口模块 ,实现AMD的容易程度以及在使用IE调用时使用Visual Studio Typescriptdebugging器的可能性。

总结 :如果按照预期使用,Typescript可以使JavaScript编程更可靠,更容易。 它可以在整个SDLC上显着提高JavaScript程序员的生产力。

所有浏览器都支持并预编译的Ecma脚本5(ES5)。 ES6 / ES2015和ES / 2016今年带来了很多变化,所以为了popup这些变化,在这之间应该有一些关于TypeScript的关注。 •TypeScript是types – >意味着我们必须定义每个属性和方法的数据types。 如果你知道C#,那么Typescript很容易理解。 •TypeScript的巨大优势是我们的身份在投入生产之前尽早input相关的问题。 这允许unit testing失败,如果有任何types不匹配。