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

Moh*_*bet 1637 javascript typescript

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

JavaScript或可用库无法做什么,这会让我有理由考虑它?

Pau*_*xon 1268

我最初写的这个答案当Typescript仍然热卖时.五年后,这是一个很好的概述,但请看下面的Lodewijk答案更深入

1000英尺的视图......

TypeScript是JavaScript的超集,主要提供可选的静态类型,类和接口.其中一个重要好处是使IDE能够在您键入代码时提供更丰富的环境来发现常见错误.

要了解我的意思,请观看Microsoft关于该语言的介绍性视频.

对于大型JavaScript项目,采用TypeScript可能会产生更强大的软件,同时仍可部署常规JavaScript应用程序.

它是开源的,但如果您使用支持的IDE,则只能在键入时获得聪明的Intellisense.最初,这只是微软的Visual Studio(也在Miguel de Icaza的博客文章中提到).目前,其他IDE也提供TypeScript支持.

还有其他类似的技术吗?

CoffeeScript,但这确实有不同的用途.恕我直言,CoffeeScript为人类提供了可读性,但TypeScript还通过其可选的静态类型为工具提供了深度可读性(请参阅最近的博客文章以获得更多批评).还有Dart,但这完全取代了JavaScript(尽管它可以生成JavaScript代码)

举个例子,这里有一些TypeScript(您可以在TypeScript Playground中使用它)

class Greeter {
    greeting: string;
    constructor (message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}  
Run Code Online (Sandbox Code Playgroud)

这是它将产生的JavaScript

var Greeter = (function () {
    function Greeter(message) {
        this.greeting = message;
    }
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    return Greeter;
})();
Run Code Online (Sandbox Code Playgroud)

注意TypeScript如何定义成员变量和类方法参数的类型.这在转换为JavaScript时被删除,但IDE和编译器使用它来发现错误,例如将数字类型传递给构造函数.

它还能够推断未明确声明的类型,例如,它将确定该greet()方法返回一个字符串.

调试Typescript

许多浏览器和IDE通过源映射提供直接调试支持.有关更多详细信息,请参阅此Stack Overflow问题:使用Visual Studio调试TypeScript代码

想知道更多?

我最初写的这个答案当Typescript仍然热卖时.查看Lodewijk对此问题的回答,了解更多当前详细信息.

  • WebStorm现在可以在TypeScript上提供出色的IntelliSense,并且是多平台的. (101认同)
  • @Erwinus:你还用汇编程序编程吗? (56认同)
  • @Erwinus TypeScript的要点是提供编译时类型检查.如果你没有看到它的价值,那就完全没问题了.TypeScript被称为"您的第一个单元测试".有许多资源可以讨论可选类型检查是否具有价值,并且比我们在这里可以做的更详细.我不是想要说服你什么,只是纠正一个误解. (41认同)
  • 这些工具的问题在于你永远无法从javascript中获得完整的性能.是的,它提供了良好的可读性,但编译的代码有时非常笨重.您依靠第三方工具编写本机javascript,我认为这不是一种方法,就像将语言转换为另一种语言一样.想要改变一种不是另一种语言的语言,就像你喜欢的另一种语言一样,这是愚蠢而愚蠢的.......(第1部分结束)...... (24认同)
  • @Erwinus您正在假设TypeScript如何工作.您可以将纯JavaScript编写为TypeScript,并让编译器只进行编译时类型检查.这样做没有性能损失. (11认同)
  • @Erwinus - 我发现你的立场是合理的,这令人难以置信.几乎所有编写良好的Windows程序都将大部分时间都用在空闲状态并等待用户交互.真正需要密集处理的例外是Sketchup,视频游戏和那些快速交易程序之类的建模软件.这些并不常见.在现代CPU上,您将从算法改进和并行化中获得比手动编码汇编器更高的性能回报.接下来你会告诉我你更愿意提供自己的电子. (8认同)
  • 不,@ Erwinus,该代码是可选的.您可以在TypeScript中轻松编写纯JavaScript版本. (7认同)
  • @Erwinus:你有没有在这里看到类比?您也可以使用javascript编程,在所有其他情况下使用typescript:它将帮助您检查类型,将提供一些intellisense.为什么不?;-) (5认同)
  • @nawfal是的我不喜欢Atom的多个进程,最终的1.0版本尚未发布,解决内存问题的是1.0的路线图,让我们看看! (4认同)
  • VS Code现在已成为WebStorm作为TypeScript编辑器的优秀轻量级(和免费)替代品,具有完整的智能感知功能,并通过tsconfig.json进行方便的项目配置. (4认同)
  • @VickciaR:为什么不呢,因为汇编程序是C语言和Delphi中的一种嵌入式语言,所以它是语言的一部分,并不是一种将语言翻译成另一种语言的语言,比如打字稿,当然还有谷歌翻译(但这是另一种语言)语言,但也是语言翻译;-)).并且......编译C语言,Delphi,汇编程序导致机器字节代码,而不是人类可读的语言,它不是解释器语言. (3认同)
  • ......(第2部分)....这与框架相同,学习框架作为语言与学习母语不同.如果您想更改语言,请使用新标准扩展语言,不要尝试修复您不喜欢的内容.如果该语言不再适合今天的要求,请更改它,不要修复它. (2认同)
  • JSDoc 注释和闭包编译器怎么样?您可以在 JavaScript 本身中进行严格的类型检查。我将它用于长期项目,并且对此非常满意。此外,像 WebStorm 这样的 IDE 已经集成了此类注释的智能感知。 (2认同)
  • Douglas Crockford对TypeScript有这样的说法:"我认为JavaScript的松散打字是其最好的功能之一,并且类型检查被高估了.TypeScript增加了甜度,但是付出了代价.这不是我愿意付出的代价. " 整个帖子都在这里.(他确实也说过好话.)https://plus.google.com/u/0/+DouglasCrockfordEsq/posts/MgzNUSTwjRt (2认同)

Lod*_*rds 1015

虽然接受的答案很好,但我觉得此刻真的没有做TypeScript公正.现在不再是早期了.现在,TypeScript正在寻找更多的应用,其中一些流行的框架是用TypeScript编写的.您现在应该选择TypeScript而不是JavaScript的原因很多.

与JavaScript的关系

TypeScript是现代JavaScript +类型.它是关于尽早捕获错误并使您成为更高效的开发人员,同时利用JavaScript社区.

JavaScript通过ECMAScript标准进行标准化.较旧的浏览器不支持较新的ECMAScript标准的所有功能(请参阅此).TypeScript支持新的ECMAScript标准,并将它们编译为您选择的(较旧的)ECMAScript目标(当前目标是3,5和6 [又名2015]).这意味着您可以使用ES2015及更高版本的功能,如模块,lambda函数,类,扩展运算符和解构,同时保持向后兼容旧版浏览器.

类型支持不是ECMAScript标准的一部分,可能永远不会归因于解释性质而不是JavaScript的编译性质.TypeScript的类型系统非常丰富,包括:接口,枚举,混合类型,泛型,联合/交集类型,访问修饰符等等.TypeScript 的官方网站概述了这些功能.今天的打字稿类型系统与其他类型语言相当,在某些情况下可以说更强大.

与其他JavaScript定位语言的关系

与其他编译为JavaScript的语言相比,TypeScript具有独特的理念.JavaScript代码是有效的TypeScript代码; TypeScript是JavaScript的超集.您几乎可以将--target文件重命名为.js文件并开始使用TypeScript(请参阅下面的"JavaScript互操作性").TypeScript文件被编译为可读的JavaScript,因此可以进行迁移,并且理解编译的TypeScript并不困难.TypeScript建立在JavaScript成功的基础上,同时改善了它的弱点.

一方面,您有未来的证明工具,它们采用现代ECMAScript标准并将其编译为较旧的JavaScript版本,其中Babel是最受欢迎的版本.另一方面,您的语言可能与针对JavaScript的JavaScript完全不同,如Coffeescript,Clojure,Dart,Elm,Haxe,ScalaJs以及更多主机(请参阅此列表).这些语言虽然可能比JavaScript未来可能带来的更好,但却没有找到足够的采用它们的未来得到保证的风险.您可能也很难找到有经验的开发人员使用这些语言,尽管您会发现这些语言通常会更热情.使用JavaScript的Interop也可以更多地涉及,因为它们实际上远离了JavaScript.

TypeScript位于这两个极端之间,从而平衡风险.TypeScript不是任何标准的危险选择.如果您熟悉JavaScript,则需要花费很少的精力,因为它不是一种完全不同的语言,具有出色的JavaScript互操作性支持,并且最近已经有很多采用.

(可选)静态类型和类型推断

JavaScript是动态类型的.这意味着JavaScript在运行时实际实例化之前不知道变量的类型.这也意味着可能为时已晚.TypeScript为JavaScript添加了类型支持.如果你正确地玩牌,你可以完全根除某些类型的某些变量的错误假设所导致的错误(你输入代码的严格程度如何,或者你输入的代码完全取决于你).

通过使用类型推断,TypeScript使输入更容易,而且更不那么明确.例如:.ts在TypeScript中与var x = "hello".相同.该类型只是从其使用中推断出来的.即使你没有明确地键入类型,它们仍然可以防止你做一些否则会导致运行时错误的事情.

默认情况下,可选择键入TypeScript.例如var x : string = "hello",TypeScript中的有效函数可以使用任何类型的参数调用,即使使用字符串调用它也会显然导致运行时错误.就像你习惯于JavaScript一样.这是有效的,因为当没有显式指定类型并且无法推断类型时,就像在divideByTwo示例中一样,TypeScript将隐式指定类型function divideByTwo(x) { return x / 2 }.这意味着divideByTwo函数的类型签名自动变为any.有一个编译器标志来禁止这种行为:function divideByTwo(x : any) : any.启用此标志可以提供更高程度的安全性,但也意味着您需要进行更多的打字.

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

有趣的是,这篇论文发现TypeScript比JavaScript更不容易出错:

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

增强的IDE支持

TypeScript的开发经验是对JavaScript的重大改进.TypeScript编译器会在其丰富的类型信息上实时通知IDE.这提供了几个主要优点.例如,使用TypeScript,您可以安全地在整个代码库中进行重构等重构.通过代码完成,您可以获得库可能提供的任何功能的内联帮助.不再需要记住它们或在在线参考中查找它们.在您忙于编码时,编译错误会直接在IDE中报告,并带有红色波浪线.总而言之,与使用JavaScript相比,这可以显着提高工作效率.人们可以花更多的时间编写代码,减少调试时间.

有各种各样的IDE对TypeScript有很好的支持,比如Visual Studio Code,WebStorm,Atom和Sublime.

严格的空检查

表单的运行时错误--noImplicitAnycannot read property 'x' of undefined通常由JavaScript代码中的错误引起.开箱即用TypeScript已经降低了发生这类错误的可能性,因为不能使用TypeScript编译器不知道的变量(undefined is not a function类型变量的属性除外).尽管错误地利用设置的变量仍然是可能的any.但是,使用2.0版本的TypeScript,您可以通过使用非可空类型来消除这些类型的错误.其工作原理如下:

启用严格空检查(undefined编译器标志)后,--strictNullChecks除非您明确声明它是可空类型,否则不允许将TypeScript编译器分配给变量.例如,undefined将导致编译错误.这完全符合类型理论,因为let x : number = undefined它不是数字.人们可以定义undefined为和的类型xnumber纠正这个:undefined.

一旦知道某个类型可以为空,意味着它的类型也可以是值,let x : number | undefined = undefined或者nullTypeScript编译器可以通过基于控制流的类型分析来确定您的代码是否可以安全地使用变量.换句话说,当您undefined通过例如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.
Run Code Online (Sandbox Code Playgroud)

在2016年的会议期间,TypeScript Anders Hejlsberg的联合设计师对此功能进行了详细解释和演示:视频(从44:30到56:30).

汇编

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

TypeScript编译器可以在生成的.js文件中内联源地图信息或创建单独的.map文件.调试实用程序(如Chrome DevTools和其他IDE)可以使用源映射信息将JavaScript中的行与在TypeScript中生成它们的行相关联.这使您可以直接在TypeScript代码上设置断点并在运行时检查变量.源地图信息非常好用,它早在TypeScript之前就已存在,但调试TypeScript通常不如直接使用JavaScript时那么好.以 --watch关键字为例.由于this自ES2015以来关键字围绕闭包的语义发生了变化,因此this在运行时可能实际上存在一个被称为变量的变量this(参见本答案).这可能会在调试期间使您感到困惑,但如果您了解它或检查JavaScript代码,通常不会出现问题.应该指出的是,巴贝尔遇到了完全相同的问题.

TypeScript编译器可以执行一些其他技巧,例如基于装饰器生成拦截代码,为不同的模块系统生成模块加载代码以及解析JSX.但是,除了Typescript编译器之外,您可能还需要一个构建工具.例如,如果要压缩代码,则必须在构建过程中添加其他工具才能执行此操作.

有适用于Webpack,Gulp,Grunt和几乎任何其他JavaScript构建工具的TypeScript编译插件.TypeScript文档有一个关于与构建工具集成的部分.一个棉短绒也可如果你想更多的建设时间检查.还有大量的种子项目可以让你开始使用TypeScript以及一些其他技术,如Angular 2,React,Ember,SystemJs,WebPack,Gulp等.

JavaScript互操作性

由于TypeScript与JavaScript密切相关,因此具有出色的互操作性功能,但在TypeScript中使用JavaScript库需要一些额外的工作.打字稿定义需要这样的打字稿编译理解函数调用像_this或者_.groupBy或者angular.copy不是真正意义上的非法语句.这些函数的定义放在$.fadeOut文件中.

定义可以采用的最简单的形式是允许以任何方式使用标识符.例如,当使用Lodash时,单行定义文件.d.ts将允许您调用您想要的任何功能declare var _ : any,但当然您仍然可以犯错:_将是合法的TypeScript调用,但当然是非法调用在运行时.如果您需要正确的类型支持和代码完成,您的定义文件需要更加精确(请参阅示例的lodash定义).

TypeScript编译器会自动理解预先打包自己的类型定义的Npm模块(请参阅文档).对于几乎没有任何其他半流行的JavaScript库,它不包含自己的定义,那里的某些人已经通过另一个npm模块提供了类型定义.这些模块以"@ types /"为前缀,来自名为DefinitelyTyped的Github存储库.

有一点需要注意:类型定义必须与您在运行时使用的库的版本相匹配.如果他们不这样做,TypeScript可能会禁止您调用函数或取消引用存在的变量或允许您调用函数或取消引用不存在的变量,这只是因为类型与编译时的运行时不匹配.因此,请确保为正在使用的库的正确版本加载正确版本的类型定义.

说实话,这有点麻烦,这可能是你不选择TypeScript的原因之一,而是选择像Babel这样的东西,它们根本不需要获得类型定义.另一方面,如果您知道自己在做什么,则可以轻松克服由于错误或缺少定义文件而导致的任何问题.

从JavaScript转换为TypeScript

_.foobar()可以将任何文件重命名为a .js并通过TypeScript编译器运行,以在语法上获得与输出相同的JavaScript代码(如果它首先在语法上是正确的).即使TypeScript编译器出现编译错误,它仍然会生成一个.ts文件.它甚至可以接受.js带有.js标志的文件作为输入.这允许您立即从TypeScript开始.不幸的是,编译错误很可能在开始时发生.人们需要记住,这些不是像你可能习惯与其他编译器一样的显示停止错误.

在将JavaScript项目转换为TypeScript项目时,编译错误在TypeScript的本质中是不可避免的.TypeScript检查所有代码的有效性,因此需要了解所有使用的函数和变量.因此,需要为所有类型定义类型定义,否则必然会发生编译错误.如上一章所述,对于几乎任何JavaScript框架,都--allowJs可以通过安装DefinitelyTyped软件包轻松获取文件.但是,您可能已经使用了一些不具有TypeScript定义的模糊库,或者您已经填充了一些JavaScript原语.在这种情况下,您必须为这些位提供类型定义,以便编译错误消失.只需创建一个.d.ts文件并将其包含在tsconfig.json的.d.ts数组中,以便TypeScript编译器始终考虑它.在其中声明TypeScript不知道的那些位作为类型files.一旦消除了所有错误,您可以根据需要逐步为这些部分引入打字.

为了将TypeScript引入构建管道,还需要一些(重新)配置构建管道的工作.正如编译章节中所提到的,那里有很多很好的资源,我鼓励你寻找使用你想要使用的工具组合的种子项目.

最大的障碍是学习曲线.我鼓励你先做一个小项目.看看它是如何工作的,如何构建,它使用哪些文件,如何配置,如何在IDE中运行,如何构建,使用哪些工具等等.当你知道将大型JavaScript代码库转换为TypeScript时是可行的你在做什么.阅读此博客,例如在72小时内将600k行转换为打字稿.只需确保在跳跃之前掌握好语言.

采用

TypeScript是开源的(Apache 2许可,请参阅github)并由Microsoft提供支持.C#的首席架构师Anders Hejlsberg正在带领该项目.这是一个非常活跃的项目; TypeScript团队在过去几年中已经发布了许多新功能,并且还计划推出许多很棒的功能(参见路线图).

2017年StackOverflow开发人员调查中, TypeScript是最受欢迎的JavaScript转换器(总体排名第9位),并且在最受欢迎的编程语言类别中获得第三名.

  • "JavaScript代码是有效的TypeScript代码" - 实际上并非总是如此.我的意思是像if(1 ==='1'){}这样的代码在TS中给出错误而在JS中却没有.但大多数时候,如果JS代码编写得很好,那就是真的. (23认同)
  • **TL; DR**在这个答案中会更安心;) (12认同)
  • @MaciejBukowski即使在这种情况下TypeScript确实会抱怨,您仍然会获得有效的JS输出(它将是使用TypeScript编译/转译的JS代码)。因此,它是“有错误的编译”,并且不是无效的TypeScript。在TypeScript规范中记录下来,任何有效的JS代码都必须是有效的TS代码。 (4认同)
  • 如果你已经失去了宝贵的生产时间心乱了丢失的分号,以打字稿写作将是一个生命的救星. (3认同)
  • 打字已被弃用,目前的最佳做法是`npm`(或`yarn`)`install @ types/foo`.你能更新你的答案吗? (3认同)
  • @Maciej Bukowski if(1 === '1') {} 不会给你一个错误,但它确实给你一个通知,你的语句总是假的(这个条件将总是返回 'false',因为类型 '1' 和'"1"' 没有重叠。) 我的意思是,如果 JavaScript 开发人员编写这样的代码,他们应该回归基础,有趣的是,我与编写 if(1+1) 或 if(true) 等 if 语句的高级开发人员一起工作) 而这些人赚了很多钱...... (2认同)

小智 77

TypeScript的功能类似于CSS或更少的功能.它们是它的超级集合,这意味着您编写的每个JS代码都是有效的TypeScript代码.另外,您可以使用它添加到语言中的其他好东西,并且转换后的代码将是有效的js.您甚至可以设置您希望生成代码的JS版本.

目前TypeScript是ES2015的超级集合,因此可能是开始学习新js功能并转换为项目所需标准的不错选择.

  • 最佳TL; DR是TS的页面:"TypeScript是JavaScript的类型超集,可编译为纯JavaScript." (3认同)

Dim*_*hev 42

" TypeScript Fundamentals " - 由Dan WahlinJohn Papa创作的Pluralsight视频课程非常好,目前(2016年3月25日)更新,以反映TypeScript 1.8,对Typescript的介绍.

对我来说,真正好的功能除了智能感知的好处之外,还有,接口,模块,实现AMD的简易性,以及在使用IE调用时使用Visual Studio Typescript调试器的可能性.

总结:如果按预期使用,Typescript可以使JavaScript编程更可靠,更容易.与完整的SDLC相比,它可以显着提高JavaScript程序员的工作效率.

  • @Oooogi,SDLC ==软件开发生命周期.AMD ==异步模块定义.后者特定于JavaScript,而前者在范围上相当通用. (15认同)
  • 什么是SDLC?AMD? (8认同)
  • “易于实施AMD,...”-我读了那本书,并认为这是某种线程撕裂程序优化之类的东西。 (2认同)

小智 14

所有浏览器支持和预编译的Ecma脚本5(ES5).ES6/ES2015和ES/2016今年出现了很多变化,所以为了弹出这些变化,两者之间应该关注所以TypeScript.

•TypeScript是Types - >意味着我们必须定义每个属性和方法的数据类型.如果您了解C#,那么Typescript很容易理解.

•TypeScript的一大优势是我们在投入生产之前就确定了与类型相关的问题.如果存在任何类型不匹配,则允许单元测试失败.

  • 这不是每年的好友!他们在经过漫长的等待后改变了规格 (2认同)
  • @SubhamTripathi每年都非常*.ES2015,ES2016,ES2017,从现在开始直到语言死亡.它*不是*每年,在2015年之前,但现在是.搜索"TC39过程"以了解更多信息. (2认同)