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

What is TypeScript and why would I use it in place of JavaScript?

你能描述一下打字语言是什么吗?

javascript或可用库不能做什么,这会给我考虑它的理由?


I originally wrote this answer when Typescript was still
hot-off-the-presses. Five years later, this is an OK overview, but look
at Lodewijk's answer below for more depth

1000英尺的视图…

typescript是javascript的超集,主要提供可选的静态类型、类和接口。其中一个最大的好处是使IDE能够在您键入代码时为发现常见错误提供更丰富的环境。

要了解我的意思,请观看微软的语言介绍视频。

对于一个大型的javascript项目,采用typescript可能会导致更健壮的软件,同时仍然可以在运行常规javascript应用程序的地方进行部署。

它是开放源码的,但只有在使用支持的IDE时才能在键入时获得智能感知。最初,这只是微软的Visual Studio(也在Miguel de Icaza的博客文章中提到)。现在,其他的IDE也提供了类型脚本支持。

还有其他类似的技术吗?

有咖啡的描述,但那确实有不同的用途。imho,coffeescript为人类提供了可读性,但typescript还通过可选的静态类型为工具提供了深度的可读性(更多评论请参阅最近的博客文章)。还有dart,但它完全替代了javascript(尽管它可以生成javascript代码)。

例子

举个例子,这里有一些字体(你可以在字体操场上使用它)

1
2
3
4
5
6
7
8
9
class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return"Hello," + this.greeting;
    }
}

这是它将产生的javascript

1
2
3
4
5
6
7
8
9
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通过源代码映射提供直接调试支持。有关详细信息,请参见此堆栈溢出问题:使用Visual Studio调试typescript代码

想知道更多吗?

我最初写这个答案的时候,打字稿还没有出版。查看Lodewijk对此问题的回答,了解更多当前的详细信息。


虽然接受的答案是好的,但我觉得它在这一点上真的不公平。现在已经不是早年了。现在,随着一些流行的框架正在用typescript编写,typescript得到了更多的采用。现在,选择typescript而不是javascript的原因很多。好的。与javascript的关系

typescript是现代的javascript+类型。它是关于及早发现错误并使您成为更高效的开发人员,同时利用JavaScript社区。好的。

JavaScript是通过ECMAScript标准进行标准化的。较旧的浏览器不支持较新ECMAScript标准的所有功能(请参阅下表)。typescript支持新的ecmascript标准,并将其编译为您选择的(旧的)ecmascript目标(当前目标为3、5和6[a.k.a.2015])。这意味着您可以使用ES2015及更高版本的功能,如模块、lambda函数、类、排列运算符和析构函数,同时保持与旧浏览器的向后兼容。好的。

类型支持不是ECMAScript标准的一部分,可能永远不会是由于解释性质而不是JavaScript的编译性质。typescript的类型系统非常丰富,包括:接口、枚举、混合类型、泛型、联合/交集类型、访问修饰符等等。TypeScript的官方网站概述了这些功能。今天,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位于这两个极端之间,从而平衡了风险。按任何标准来说,打字稿都不是一个冒险的选择。如果你熟悉JavaScript,你就不需要太多的努力去适应它,因为它不是一种完全不同的语言,具有出色的JavaScript互操作性支持,而且最近它已经被大量采用。好的。可选静态类型和类型推断

javascript是动态类型的。这意味着在运行时实际实例化变量之前,JavaScript不知道变量是什么类型。这也意味着可能为时已晚。typescript为javascript添加了类型支持。如果你打对牌(你输入代码的严格程度,或者你输入代码的严格程度取决于你),由某种类型的变量的错误假设引起的错误可以完全消除。好的。

通过使用类型推断,typescript使键入变得更简单,也更不显式。例如:typescript中的var x ="hello"var x : string ="hello"相同。类型只是从其使用中推断出来的。即使您没有显式地键入类型,它们仍然存在,以避免您执行某些操作,否则会导致运行时错误。好的。

默认情况下,类型脚本是可选的。例如,function divideByTwo(x) { return x / 2 }是typescript中的一个有效函数,可以用任何类型的参数调用它,尽管用字符串调用它显然会导致运行时错误。就像你在javascript中习惯的那样。这是有效的,因为当没有显式分配类型并且无法推断类型时,就像在dividebyto2示例中一样,typescript将隐式分配类型any。这意味着dividedBytwo函数的类型签名自动变为function divideByTwo(x : any) : any。有一个编译器标志禁止这种行为:--noImplicitAny。启用此标志可以提高安全性,但也意味着您必须进行更多的键入。好的。

类型具有相关联的成本。首先有一个学习曲线,其次,当然,使用适当的严格类型设置代码库也会花费更多的时间。根据我的经验,这些成本完全值得你与他人分享任何严肃的代码库。对Github中编程语言和代码质量的大规模研究表明,"通常静态类型语言比动态类型更不容易出现缺陷,在相同方面,强类型优于弱类型"。好的。

有趣的是,这篇文章发现typescript比javascript更不容易出错:好的。

For those with positive coefficients we can expect that the language
is associated with, ceteris paribus, a greater number of defect fixes.
These languages include C, C++, JavaScript, Objective-C, Php, and
Python. The languages Clojure, Haskell, Ruby, Scala, and TypeScript,
all have negative coefficients implying that these languages are less
likely than the average to result in defect fixing commits.

Ok.

增强的IDE支持

typescript的开发经验比javascript有了很大的改进。类型脚本编译器会实时通知IDE其丰富的类型信息。这有两个主要优势。例如,使用typescript,您可以在整个代码库中安全地进行重构,如重命名。通过代码完成,您可以获得关于库可能提供的任何函数的内联帮助。不再需要记住它们或在在线参考资料中查找它们。当您忙于编码时,编译错误会直接在IDE中以一条红色的弯弯曲曲的线报告。总之,与使用JavaScript相比,这可以显著提高工作效率。一个人可以花费更多的时间编码和更少的时间调试。好的。

有各种各样的IDE都非常支持类型脚本,比如Visual Studio代码、Webstorm、Atom和Sublime。好的。严格的空检查

cannot read property 'x' of undefinedundefined is not a function形式的运行时错误通常是由javascript代码中的错误引起的。开箱即用的typescript已经降低了发生此类错误的可能性,因为不能使用typescript编译器不知道的变量(any类型变量的属性除外)。但仍有可能错误地使用设置为undefined的变量。但是,使用2.0版的typescript,您可以通过使用不可为空的类型来消除这些类型的错误。其工作原理如下:好的。

如果启用了严格的空检查(--strictNullChecks编译器标志),除非显式声明为可空类型,否则typescript编译器将不允许将undefined分配给变量。例如,let x : number = undefined将导致编译错误。这完全符合类型理论,因为undefined不是一个数字。可以将x定义为numberundefined的和类型,以更正这一点:let x : number | undefined = undefined。好的。

一旦知道一个类型可以为空,也就是说它是一个值也可以为nullundefined的类型,typescript编译器就可以通过基于控制流的类型分析来确定代码是否可以安全地使用变量。换句话说,当您检查一个变量是否为undefined到(例如if语句)时,typescript编译器将推断代码控制流分支中的类型不再可以为空,因此可以安全地使用。下面是一个简单的例子:好的。

1
2
3
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.

在构建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关键字的语义发生了变化,因此this可能在运行时作为一个名为_this的变量存在(见此答案)。在调试过程中,这可能会使您感到困惑,但如果您了解它或检查JavaScript代码,则通常不会出现问题。值得注意的是,巴别塔也面临着同样的问题。好的。

typescript编译器还可以使用其他一些技巧,比如基于装饰器生成截取代码、为不同的模块系统生成模块加载代码以及解析JSX。但是,除了类型脚本编译器之外,您可能还需要一个构建工具。例如,如果要压缩代码,则必须向构建过程中添加其他工具才能进行压缩。好的。

有一些类型脚本编译插件可用于Webpack、Gulp、Grunt和几乎所有其他的javascript构建工具。typescript文档中有一个关于与涵盖所有内容的构建工具集成的部分。如果您想要更多的构建时间检查,也可以使用一个过梁。还有大量的种子项目可以让你从typescript开始,结合其他一些技术,比如angular 2、react、ember、systemjs、webpack、gulp等等。好的。JavaScript互操作性

由于typescript与javascript的关系非常密切,它具有很强的互操作性,但是在typescript中使用javascript库需要做一些额外的工作。需要使用typescript定义,以便typescript编译器理解,像_.groupByangular.copy$.fadeOut这样的函数调用实际上不是非法语句。这些函数的定义放在.d.ts文件中。好的。

定义可以采用的最简单形式是允许以任何方式使用标识符。例如,当使用lodash时,单行定义文件declare var _ : any允许您调用_上所需的任何函数,但当然,您仍然可以犯错误:_.foobar()是合法的typescript调用,但在运行时当然是非法调用。如果您想要适当的类型支持和代码完成,您的定义文件需要更精确(请参见lodash定义的例子)。好的。

带有自己类型定义的预打包的NPM模块由类型脚本编译器自动理解(请参阅文档)。对于几乎所有其他不包含自己定义的半流行的JavaScript库,已经有人通过另一个NPM模块提供了类型定义。这些模块的前缀是"@types/",来自一个名为definitelytyped的Github存储库。好的。

有一个警告:类型定义必须与您在运行时使用的库的版本匹配。如果没有,typescript可能不允许您调用函数或取消对现有变量的引用,或者不允许您调用函数或取消对不存在变量的引用,这仅仅是因为类型在编译时与运行时不匹配。因此,请确保为所使用的库的正确版本加载正确版本的类型定义。好的。

老实说,这有点麻烦,这可能是您不选择typescript的原因之一,而是选择像babel这样完全不需要获取类型定义的东西。另一方面,如果你知道你在做什么,你可以很容易地克服由不正确或缺少定义文件引起的任何问题。好的。从Javascript转换到Typescript(P)Any EDOCX1 0 silian file can be renamed to a EDOCX1 university 1 and ran through the typescript compiler to get syntactically the same Javascript code as an output(if it was syntactically correct in the first place).即使是当暴发的竞争对手得到了汇编错误,它仍然会产生一个字母化的DOECX1。它甚至可以接受EDOCX1的英文字母0,作为输入的文件与EDOCX1This allows you to start with typescript right away.没有及时地汇编错误,这在初创阶段是一样的。一个不需要记住,他们不是表演-停止错误喜欢你可能会被用来对付其他的竞争对手。好的,好的。(P)The compilation errors one gets in the beginning when turning a Javascript project to a typescript project are unavoidable by typescrit's nature.Typescrit checks all code for validity and thus it need to know about all functions and variables that are used.Thus type definitions need to be in place for all of them otherwise compilation errors are bound to occur.As mentioned in the chapter above,for pretty much any javascript framework there are EDOCX1 penographic 5 communal files that can easily be acquired with the instalation of definitelytyped packages.It might however be that you've used some blackure library for which no typescript definitions are available or that you've polyfilled some javascript priorities.In that case you must supply type definitions for these bits in order for the compilation errors to dissapear.Just create a EDOCX1 penographic 5 nical file and include it in the tsconfig.json's EDOCX1 penographic 7 allay,so it is always considered by the typescript compiler.在这一点上,有人说,typescrit does not know about as type EDOCX1.Once you've eliminated all errors you can gradally introduce typing to those parts according to your needs.好的,好的。(P)Some work on(re)configuring your build pipeline will also be need to get typescript into the build pipeline.As mentioned in the chapter on compilation there are plenty of good resources out there and I encourage you to look for seed projects that use the combination of tools you want to be working with.好的,好的。(P)Biggest hurdle is the learning curve.我鼓励你和一个小项目一起在周围玩耍。Look how it works,how it builds,which files it used,how it is configured,how it functions in your ide,how it is structured,which tools it used,etc.Conducting a large javascript code to typescrip is doable when you know what you are doing.阅读此博客以实例说明将600K行转换为72小时的类型)。Just make sure you have a good grasp of the language before you make the jump.好的,好的。采用

typescript是开源的(Apache2获得许可,请参阅GitHub),由Microsoft提供支持。C的首席建筑师安德斯·赫杰斯伯格(Anders Hejlsberg)是该项目的先锋。这是一个非常活跃的项目;在过去的几年中,排版团队已经发布了很多新的功能,而且很多伟大的功能仍在计划之中(见路线图)。好的。

在2017年StackOverflow开发者调查中,typescript是最受欢迎的javascript发起者(排名第9位),在最受欢迎的编程语言类别中排名第三。好的。好啊。


typescript的作用类似于less或sass对css的作用。它们是它的超级集合,这意味着您编写的每个JS代码都是有效的typescript代码。另外,您还可以使用它添加到语言中的其他优点,并且发出的代码将是有效的JS。您甚至可以设置您想要结果代码的JS版本。

目前,typescript是ES2015的一个超级集合,因此可能是开始学习新的JS特性并发展到项目所需标准的一个好选择。


"打字脚本基础知识"--丹·瓦林和约翰·帕帕的一个多视角视频课程非常好,目前(2016年3月25日)更新以反映打字脚本1.8,打字脚本介绍。

对我来说,除了IntelliSense的好功能外,真正好的功能还有类、接口、模块、实现AMD的易用性,以及使用IE调用时使用Visual Studio TypeScript调试器的可能性。

总结:如果按预期使用,typescript可以使JavaScript编程更可靠、更容易。它可以显著提高JavaScript程序员在整个SDLC中的工作效率。


所有浏览器都支持并预编译的ECMA脚本5(ES5)。ES6/ES2015和ES/2016今年带来了很多变化,所以为了弹出这些变化,中间应该有一些东西需要注意,所以打印脚本。

?typescript是types->意味着我们必须定义每个属性和方法的数据类型。如果你知道C,那么打字脚本很容易理解。

?typescript的最大优点是我们在生产之前就识别与类型相关的问题。这允许单元测试在任何类型不匹配时失败。