什么是TypeScript,为什么我要用它来代替JavaScript?[已关闭]

h43kikqp  于 2023-02-02  发布在  Java
关注(0)|答案(5)|浏览(169)

已关闭。此问题需要超过focused。当前不接受答案。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

5年前关闭。
Improve this question
你能描述一下什么是TypeScript语言吗?
它能做什么JavaScript或可用库不能做的,这会给予我考虑它的理由?

hsgswve4

hsgswve41#

我最初写这个答案的时候,TypeScript还很热。五年后,这是一个不错的概述,但是请看下面的Lodewijk's answer以获得更深入的信息

1000英尺的视野...

TypeScript是JavaScript的一个超集,主要提供可选的静态类型、类和接口。最大的好处之一是使IDE能够提供一个更丰富的环境,以便在键入代码时 * 发现常见错误 *。
要理解我的意思,请观看Microsoft's introductory video的语言。
对于大型JavaScript项目,采用TypeScript可能会产生更健壮的软件,同时仍然可以部署到常规JavaScript应用程序运行的地方。
它是开源的,但只有在使用支持的IDE时,你才能在输入时获得智能感知。最初,这只是微软的Visual Studio(Miguel de Icaza的博客文章也提到了这一点)。

是否有其他类似的技术?

还有CoffeeScript,但它实际上服务于一个不同的目的。恕我直言,CoffeeScript为人类提供了可读性,但TypeScript也通过其可选的静态类型为 * 工具 * 提供了深度可读性(更多评论请参见recent blog post)。还有Dart,但它完全取代了JavaScript(尽管它是can produce JavaScript code

示例

例如,这里有一些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如何定义成员变量和类方法参数的类型。在转换为JavaScript时会将其删除,但IDE和编译器会使用它来发现错误,例如将数值类型传递给构造函数。
它还能够推断没有显式声明的类型,例如,它将确定greet()方法返回字符串。

调试类型脚本

许多浏览器和IDE都通过源Map提供直接调试支持。有关详细信息,请参阅堆栈溢出问题:Debugging TypeScript code with Visual Studio

想要了解更多信息?

我最初写这个答案的时候,TypeScript还很热。查看Lodewijk's answer这个问题的一些更当前的细节。

xurqigkl

xurqigkl2#

类型脚本与JavaScript的关系

TypeScript是JavaScript的类型化超集,可编译为纯JavaScript -typescriptlang.org
JavaScript是由ECMA's Technical Committee 39开发的一种编程语言,ECMA's Technical Committee 39是由许多不同利益相关者组成的一个小组,TC 39是由ECMA主持的一个委员会:一个内部标准组织。JavaScript有许多不同的实现由许多不同的供应商(如谷歌,微软,甲骨文等)。JavaScript的目标是成为网络的通用语言。
TypeScript是JavaScript语言的超集,它有一个开源编译器,主要由一个供应商开发:TypeScript的目标是帮助在类型系统中及早捕捉错误,并使JavaScript开发更高效。
本质上,TypeScript通过三种方式实现其目标:
1.支持现代JavaScript功能-JavaScript语言(不是运行时)通过ECMAScript标准进行标准化。并非所有浏览器和JavaScript运行时都支持所有ECMAScript标准的所有功能TypeScript允许使用许多最新的ECMAScript功能,并将它们转换为您选择的较旧的ECMAScript目标(参见--target编译器选项下的compile targets列表)这意味着您可以安全地使用新特性,如模块、lambda函数、类、spread运算符和解构,同时保持与旧浏览器和JavaScript运行时的向后兼容。
1.高级类型系统-类型支持不是ECMAScript标准的一部分,而且可能永远不会支持,这是因为JavaScript的解释性质而不是编译性质。TypeScript的类型系统非常丰富,包括:接口、枚举、混合类型、泛型、并集/交集类型、访问修饰符等等。TypeScript的official website概述了这些特性。Typescript的类型系统与大多数其他类型化语言不相上下,在某些情况下可以说更强大。
1.开发人员工具支持- 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、Haex、Scala.js等(参见list)。尽管这些语言可能比JavaScript的未来更好,但它们面临着无法获得足够的采用以保证其未来的更大风险。您可能也很难找到其中一些语言的有经验的开发人员,虽然你会发现那些通常会更热情。与JavaScript的互操作性也会更多一点,因为它们与JavaScript的实际情况相距甚远。
TypeScript位于这两个极端之间,因此平衡了风险。以任何标准衡量,TypeScript都不是一个有风险的选择。如果你熟悉JavaScript,它不需要付出什么努力就可以适应,因为它不是一种完全不同的语言,具有出色的JavaScript互操作性支持,而且最近得到了大量采用。

可选静态类型和类型推断

JavaScript是动态类型化的。这意味着JavaScript不知道变量是什么类型,直到它在运行时实际示例化。这也意味着可能为时已晚。TypeScript为JavaScript添加了类型支持,并在编译JavaScript时捕获类型错误。如果你的策略正确,错误地假设某个变量是某种类型所导致的错误可以完全消除(您键入代码的严格程度或是否键入代码完全取决于您)。
TypeScript通过使用类型推断使键入变得更容易,并且不那么显式。例如:TypeScript中的var x = "hello"var x : string = "hello"相同。类型只是从它的使用中推断出来的。即使你没有显式地键入类型,它们仍然存在,以保存你做一些否则会导致运行时错误的事情。

TypeScript在默认情况下是可选类型的。例如,function divideByTwo(x) { return x / 2 }是TypeScript中的一个有效函数,它可以用 * 任何 * 类型的参数调用,即使用字符串调用它显然会导致 runtime 错误。就像你在JavaScript中所习惯的那样。这是有效的,因为当没有显式分配类型并且无法推断类型时,就像divideByTwo示例中那样,TypeScript将隐式分配类型any。这意味着divideByTwo函数的类型签名自动变为function divideByTwo(x : any) : any。有一个编译器标志禁止此行为:--noImplicitAny。启用此标志可以提高安全性,但也意味着您将不得不进行更多的输入。
类型是有代价的。首先,有一个学习曲线,其次,当然,使用正确的严格类型设置代码库也会花费您多一点的时间。根据我的经验,这些代价对于您与他人共享的任何严肃的代码库来说都是完全值得的。A Large Scale Study of Programming Languages and Code Quality in Github建议 “静态类型语言,一般来说,动态类型比动态类型更不容易出现缺陷,并且在相同方面强类型比弱类型更好”。
有趣的是,这篇论文发现TypeScript比JavaScript更不容易出错:
对于那些系数为正的语言,我们可以预期,在其他条件不变的情况下,该语言与更多的缺陷修复相关,这些语言包括C、C++、JavaScript、Objective-C、Php和Python,而Clojure、Haskell、Ruby、Scala和 TypeScript 等语言的系数都为负,这意味着这些语言导致缺陷修复提交的可能性低于平均水平。

增强的IDE支持

与JavaScript相比,使用TypeScript的开发体验是一个巨大的改进。TypeScript编译器会实时通知IDE其丰富的类型信息。这提供了两个主要优势。例如,使用TypeScript,您可以安全地在整个代码库中执行重命名之类的重构。通过代码完成,你可以得到库提供的任何函数的内联帮助。2不再需要记住它们或在在线参考中查找它们。3当你忙碌编码时,编译错误会直接在IDE中用红色的波浪线报告。总而言之,与使用JavaScript相比,这可以显著提高工作效率,可以花更多的时间编码,更少的时间调试。
有很多IDE都对TypeScript有很好的支持,比如Visual Studio Code、WebStorm、Atom和Sublime。

严格的空值检查

cannot read property 'x' of undefinedundefined is not a function形式的运行时错误通常是由JavaScript代码中的bug引起的。开箱即用的TypeScript已经降低了这类错误发生的概率。因为不能使用TypeScript编译器未知的变量(any类型变量的属性除外)。尽管如此,仍有可能错误地使用设置为undefined的变量。但是,在2.0版本的TypeScript中,你可以通过使用非空类型来消除这些类型的错误。2其工作原理如下:
启用严格空值检查(--strictNullChecks编译器标志)TypeScript编译器将不允许将undefined赋给变量,除非显式将其声明为可空类型。例如,let x : number = undefined将导致编译错误。这完全符合类型理论,因为undefined不是数字。可以将x定义为numberundefined的求和类型来纠正这一点:x1米20英寸
一旦已知一个类型是可空的,这意味着它的类型也可以是值nullundefined,TypeScript编译器可以通过基于控制流的类型分析来确定您的代码是否可以安全地使用变量。换句话说,当您通过例如if语句检查变量是否为undefined时,TypeScript编译器将推断代码的该分支中的类型为“的控制流不再可以为空,因此可以安全地使用。下面是一个简单的示例:

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对此功能进行了详细的解释和演示:video(从44时30分到56时30分)。

汇编

要使用TypeScript,您需要一个编译为JavaScript代码的构建过程。构建过程通常只需要几秒钟,当然这取决于项目的大小。TypeScript编译器支持增量编译(--watch编译器标志),因此可以以更快的速度编译所有后续更改。

TypeScript编译器可以在生成的. js文件中内联源Map信息,也可以创建单独的. map文件。Chrome DevTools和其他IDE等调试实用程序可以使用源Map信息,将JavaScript中的行与在TypeScript中生成它们的行关联起来。这样,您就可以在运行时直接在TypeScript代码上设置断点并检查变量。源代码Map信息工作得很好,它早在TypeScript之前就存在了,但是调试TypeScript通常没有直接使用JavaScript那么好,以this关键字为例,由于自ES2015以来闭包周围的this关键字的语义发生了变化,this可能在运行时以变量_this的形式存在(参见此答案)。这可能会在调试期间让您感到困惑,但如果您了解它或检查JavaScript代码,通常不会有问题。应该注意的是,Babel遇到了完全相同的问题。
TypeScript编译器还可以做一些其他的技巧,比如生成基于decorators的拦截代码,为不同的模块系统生成模块加载代码,以及解析JSX。但是,除了Typescript编译器之外,你可能还需要一个构建工具。例如,如果你想压缩你的代码,你必须在构建过程中添加其他工具来完成。
提供了适用于WebpackGulpGrunt和几乎所有其他JavaScript构建工具。TypeScript文档中有一个关于integrating with build tools的章节涵盖了所有这些工具。如果你想进行更多的构建时间检查,也可以使用linter。还有大量的种子项目可以让你开始使用TypeScript和其他一些技术,比如Angular 2、React、Ember、SystemJS、Webpack、Gulp等等。

JavaScript互操作性

由于TypeScript与JavaScript密切相关,因此它具有很强的互操作性,但是在TypeScript中使用JavaScript库需要做一些额外的工作。需要TypeScript definitions,以便TypeScript编译器理解像_.groupByangular.copy$.fadeOut这样的函数调用实际上不是非法语句。这些函数的定义位于.d.ts文件中。
定义最简单的形式是允许标识符以任何方式使用,例如,当使用Lodash时,一个单行定义文件declare var _ : any将允许您在_上调用任何您想要的函数,但是,当然,您仍然可能出错:_.foobar()将是合法的TypeScript调用,但当然在运行时是非法调用。如果您想要适当的类型支持和代码完成,您的定义文件需要更精确(有关示例,请参见lodash definitions)。
Npm modules预先打包了自己的类型定义,TypeScript编译器会自动理解它(参见documentation)。对于几乎任何其他不包含自己定义的半流行JavaScript库,已经有人通过另一个npm模块提供了类型定义。这些模块以"@types/"为前缀,来自Github库,称为DefinitelyTyped。
有一点需要注意:类型定义必须与您在运行时使用的库版本匹配。如果不匹配,TypeScript可能不允许您调用函数或取消引用已存在的变量,或者允许您调用不存在的函数或取消引用不存在的变量,这仅仅是因为类型在编译时与运行时不匹配。因此,请确保为所使用的库的正确版本加载类型定义的正确版本。
老实说,这有一点麻烦,这可能是你不选择TypeScript的原因之一,而是选择像Babel这样的东西,它根本不需要类型定义。另一方面,如果你知道你在做什么,你可以很容易地克服任何由不正确或丢失定义文件引起的问题。

从JavaScript转换为TypeScript

任何.js文件都可以重命名为.ts文件,并通过TypeScript编译器运行,以获得语法上相同的JavaScript代码作为输出(如果它在语法上是正确的)。即使当TypeScript编译器得到编译错误,它仍然会产生一个.js文件。它甚至可以接受带有--allowJs标志的.js文件作为输入,这允许您立即开始使用TypeScript。编译错误很可能发生在开始的时候。需要记住的是,这些错误并不是像你在其他编译器中所习惯的那样会停止显示。

从一开始将JavaScript项目转换为TypeScript项目时,编译错误是TypeScript的本性所不可避免的。TypeScript检查 * 所有 * 代码的有效性,因此它需要知道所有使用的函数和变量。因此,类型定义需要为所有这些函数和变量准备好,否则编译错误一定会发生。正如上一章所提到的,对于几乎所有的JavaScript框架,都有.d.ts文件,可以通过安装DefinitelyTyped包轻松获得。然而,可能您使用了一些晦涩的库,其中没有可用的TypeScript定义,或者您对一些JavaScript原语进行了多边形填充。在这种情况下,你必须为这些位提供类型定义以消除编译错误。只需创建一个.d.ts文件并将其包含在tsconfig.json的files数组中,以便TypeScript编译器始终考虑它。在它中,TypeScript将不知道的那些位声明为类型any。We“我已经排除了所有的错误,你可以根据自己的需要逐步把打字引入那些部分。
为了让TypeScript进入构建管道,还需要做一些(重新)配置构建管道的工作。正如在关于编译的章节中提到的,有很多好的资源,我鼓励你寻找使用你想使用的工具组合的种子项目。
最大的障碍是学习曲线。我鼓励你一开始先玩一个小项目。看看它是如何工作的,它是如何构建的,它使用哪些文件,它是如何配置的,它在你的IDE中是如何工作的,它是如何结构化的,它使用哪些工具,当你知道你在做什么的时候,把一个大的JavaScript代码库转换成TypeScript是可行的。阅读这个博客,例如converting 600k lines to typescript in 72 hours。在你跳之前,一定要很好地掌握这门语言。

追加

TypeScript是开源的(Apache2许可,见GitHub),由微软支持。Anders Hejlsberg是C#的首席架构师,是这个项目的先锋。TypeScript团队在过去的几年里发布了很多新特性,而且还有很多很棒的特性仍在计划中(参见roadmap)。
关于采用率和受欢迎程度的一些事实:

  • 在2017年StackOverflow开发者调查中,TypeScript是最受欢迎的JavaScript翻译器(第9名),并在最受欢迎的编程语言类别中获得第三名。
  • 2018 state of js survey中,TypeScript被宣布为JavaScript风格类别中的两大赢家之一(ES6是另一个)。
  • 2019 StackOverflow developer survey中,TypeScript上升到专业开发人员中最流行语言的第9位,超过了C和C++。它再次在大多数最受欢迎的语言中排名第三。
  • 在2020年StackOverflow开发者调查中,TypeScript是第二受欢迎的技术。
qacovj5a

qacovj5a3#

TypeScript的作用类似于less或sass对CSS的作用。它们是CSS的超集,这意味着你写的每一个JS代码都是有效的TypeScript代码。另外,你可以使用它添加到语言中的其他好处,翻译的代码将是有效的js。你甚至可以设置你想要的结果代码的JS版本。
目前,TypeScript是ES2015的一个超级集合,所以开始学习新的js特性并移植到您的项目所需的标准可能是一个很好的选择。

1wnzp6jl

1wnzp6jl4#

TypeScript Fundamentals”--由**Dan WahlinJohn Papa**提供的Pluralsight视频课程非常好,目前(2016年3月25日)更新以反映TypeScript 1.8,介绍Typescript。
对我来说,除了智能感知的可能性之外,真正好的特性是 * 类 接口 模块 *、实现AMD的容易性,以及在使用IE调用时使用Visual Studio Typescript调试器的可能性。

总结:如果按预期使用,Typescript可以使JavaScript编程更可靠、更容易,它可以大大提高JavaScript程序员的工作效率,超过完整的SDLC。

cbeh67ev

cbeh67ev5#

Ecma脚本5(ES 5),所有浏览器都支持和预编译。ES6/ES 2015和ES/2016今年来了很多变化,所以弹出这些变化之间有一些应该注意的东西,所以TypeScript。
· TypeScript是类型-〉意味着我们必须定义每个属性和方法的数据类型。如果你懂C#,那么Typescript很容易理解。
·TypeScript的一大优势是我们可以在投入生产之前及早识别与类型相关的问题,这使得单元测试在出现任何类型不匹配时都可以失败。

相关问题