微软脚本编程语言-TypeScript


TypeScript 是微软新推出的基于JavaScript的一种开源编程语言,兼容于JavaScript,可以载入JavaScript代码然后运行。TypeScript不仅包含JavaScript的语法,而且还提供了静态类型检查以及使用看起来像基于类的面向对象编程语法操作 Prototype。C#的首席架构师以及Delphi和Turbo Pascal的创始人安德斯·海尔斯伯格参与了TypeScript的开发。从v6.0起将编译器和工具链将从TypeScript移植到Go语言。

TypeScript是为开发大型应用而设计的,并且其可转译成JavaScript。由于TypeScript是JavaScript的严格超集,任何现有的JavaScript程序都是合法的TypeScript程序。支持为现存JavaScript库添加类型信息的定义文件,方便其他程序像使用静态类型的值一样使用现有库中的值。目前有第三方提供常用库如jQuery、MongoDB、Node.js和D3.js的定义文件。编译器本身也是用TypeScript编写,并被转译为JavaScript,以Apache许可证第二版发布。
与JavaScript 相比,进步的地方包括:加入注释,让编译器理解所支持的对象和函数,编译器会移除注释,不会增加开销;增加一个完整的类结构,使之成为一个全新的面向对象语言。
语言特性
TypeScript是一种给JavaScript添加特性的语言扩展。增加的功能包括:
类型批注和编译时类型检查
类型推断
类型擦除
接口
枚举
Mixin
泛型编程
名字空间
元组
Await
以下功能是从ECMA 2015反向移植而来:
类
模块
lambda函数的箭头语法
可选参数以及默认参数
在语法上,TypeScript很类似JScript .NET,它是另外一个微软对ECMA-262语言标准的实现,添加了对静态类型、经典的面向对象语言特性(如类、继承、接口和名字空间等)的支持。
示例代码:
class Greeter {
constructor(public greeting: string) { }
greet() {
return "" + this.greeting + "";
}
};
var greeter = new Greeter("Hello, FreeOA!");
var str = greeter.greet();
document.body.innerHTML = str;
始于JavaScript,归于JavaScript
TypeScript从今天数以百万计的JavaScript开发者所熟悉的语法和语义开始。使用现有的JavaScript代码,包括流行的JavaScript库,并从JavaScript代码中调用TypeScript代码。它可以编译出纯净、 简洁的JavaScript代码,并且可以运行在任何浏览器上、Node.js环境中和任何支持ECMAScript 3(或更高版本)的JavaScript引擎中。
强大的工具构建 大型应用程序
类型允许JavaScript开发者在开发JavaScript应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。类型是可选的,类型推断让一些类型的注释使你的代码的静态验证有很大的不同。类型让你定义软件组件之间的接口和洞察现有JavaScript库的行为。
先进的 JavaScript
TypeScript提供最新的和不断发展的JavaScript特性,包括那些来自2015年的ECMAScript和未来的提案中的特性,比如异步功能和Decorators,以帮助建立健壮的组件。这些特性为高可信应用程序开发时是可用的,但是会被编译成简洁的ECMAScript3(或更新版本)的JavaScript。
TypeScript 编程语言团队于2021年3月10日宣布已重写 TypeScript 手册,该手册是学习 TypeScript 语言及其常用用法的主要资源。新手册在团队中已经是一个运行多年的项目,包含了大大小小的数百个贡献。据团队的说法,其在过去的一年里扩大了文档的规模、现代化程度以及范围。现在该手册是 TypeScript 语言文档中最重要的部分。重写工作的重点在于对 TypeScript 的教学方式进行了几处更改。包括省去讲授 JavaScript(因为网络上和相关书籍资源已经非常丰富了)、渐进式教学、每当发布新的 TypeScript 版本时提供最新的代码示例,以及编写日常用例。通过专注于这些领域,团队可以为 TypeScript 语言提供更加集中和简单易懂的介绍。 官方表示,在阅读该手册之后,开发人员应该能够阅读和理解常用的 TypeScript 语法和模式,解释编译器选项的效果以及预测大多数用例的类型系统行为。
阅读新手册:Web / Epub / PDF
《TypeScript 教程》是一份由阮一峰所编译的TypeScript开源教程,介绍基本概念和用法,面向初学者。阮表示在2023年3月份快写完这份教程的时候,TypeScript 5.0 突然发布了。装饰器(Decorators)改用全新语法。因此他重写了这一章,于是装饰器现在就有新语法和旧语法两章,因为 TypeScript 同时支持这两者。亦可参见Github开源地址。
用于微型物联网设备的DeviceScript
DeviceScript 为基于低资源微控制器的设备带来了专业的 TypeScript 开发人员体验。其被编译为自定义 VM 字节码,可以在非常受限的环境中运行,采用MIT协议授权。特性如下:
TypeScript for IoT
熟悉的语法和工具,尽在你的指尖。
Small Runtime
低功耗 / 闪存 / 内存的字节码解释器。
Hardware as Services
传感器和执行器的客户端 / 服务器架构。
Debugging
在 Visual Studio Code 中,用于嵌入式硬件或模拟设备。
Simulation and Testing
使用硬件 / 模拟传感器开发和测试你的固件。CI 友好。
Development Gateway
具有设备管理、固件部署和消息队列的 Prototype cloud service。
为性能考量将编译器和工具链将移植到 Go
TypeScript、C#、Delphi 语言之父 Anders Hejlsberg 于2025年3月中旬在 Microsoft 开发者博客宣布重大消息:TypeScript 编译器以及工具链将移植到 Go 语言,性能提升高达 10 倍!
这一举动旨在解决 TypeScript 在大型代码库中性能瓶颈的问题,为开发者带来更流畅、更高效的开发体验。根据官方公布的数据,新的原生实现将带来以下惊人的改进:
1.编辑器启动的项目加载速度提升 8 倍
2.大多数构建时间缩短 10 倍
3.内存使用量大幅减少
通过移植当前代码库,预计能够在2025年中期预览能够进行命令行类型检查的tsc的原生实现,并在年底前提供用于项目构建和语言服务的功能完整解决方案。可以从我们新的工作仓库构建和运行Go代码,该仓库与现有TypeScript代码库采用相同的许可证提供。查看README获取有关如何构建和运行tsc和语言服务器的说明,以及查看目前已实现功能的摘要。随着新功能可供测试,我们将定期发布更新。以下是在GitHub上运行tsc对不同大小的一些流行代码库的时间:

Anders Hejlsberg 和 TypeScript 团队在 GitHub 仓库的讨论区解释了为何采用 Go,主要原因有以下几点:
1.代码结构相似性:TypeScript 现有代码库采用函数式编程风格,很少使用类。而 Go 语言也以函数和数据结构为中心,与现有代码结构高度相似,这使得移植工作更加容易。
2.内存管理:Go 语言提供自动垃圾回收(GC),无需开发者手动管理内存,这大大简化了移植过程,降低了代码复杂度。同时,Go 的 GC 对 TypeScript 编译器这类批处理任务影响很小。
3.内存布局控制:Go 语言允许对内存布局和分配进行精细控制,这对于优化性能至关重要。
4.图处理能力:TypeScript 编译器涉及大量的树遍历和多态节点处理,Go 语言在这方面表现出色。
Anders Hejlsberg 强调,这是一次 “移植” 而非 “重写”,目标是尽可能保留现有代码库的结构和语义,确保兼容性。Go 语言的特性与 TypeScript 现有代码库的契合度最高,是 “阻力最小” 的路径。最近的TypeScript版本是TypeScript v5.8,v5.9即将推出。基于JS的代码库将继续开发到6.x系列,v6.0将引入一些弃用和破坏性变更,以与即将推出的原生代码库保持一致。当原生代码库达到与当前TypeScript足够的对等性时将发布它作为v7.0。这仍在开发中,将在稳定性和功能里程碑发生时宣布。为了清晰起见,我们将简单地将它们称为TypeScript 6(JS)和TypeScript 7(原生),因为这将是可预见未来的命名法。在内部讨论或代码注释中,您可能还会看到我们提到"Strada"(原始TypeScript代号)和"Corsa"(此项工作的代号)。
为什么微软不用自己的C#来做这个事情,而是用了Google的Go语言?
其实这跟微软的传统有关。我们知道微软一直是操作系统和编程语言的“大厂”,Windows和Visual Studio都世界闻名。同时微软也有一个传统,叫“Eat Dog Food”。这里的“吃狗粮”,不是吃恋爱的狗粮,看见对面拥抱亲亲就想看死对面的那种,而是微软内部就使用开发中的Windows作为平台,再使用自家的编程工具(VC、C#)来编写软件。
在使用的过程中,把遇到的问题反馈到公司内部的开发小组,让他们持续改进。因为是内部沟通,成本很低,速度很快。这也是微软早期的成功秘诀之一。
那这次为什么TypeScript没有用C#,而是用Go呢?
其实有一个采访,TypeScript的作者之一,著名的“Delphi之父”-Anders出面说明了这个问题。原因据说有2个:
1、Go其实比C#更加底层,更接近原生。但是同时Go还具有GC-“内存自动回收”这个超级大利器。而C#是一种“IL”语言,需要NetCore平台的支持,相比较Go无敌的“跨平台编译只需要改变一个变量”的机制还有相当大的差距。这一点,其实是Go吸取了Plan9的优点。Plan9作为Unix发明者开发的下一代“改良平台”,虽然不是很成功,但是其中的很多思想是非常先进的。而同为Plan9开发者的开发的Go,其实从Plan9吸取了很多东西,包括其特殊使用的跨平台编译器,channel机制,无疑都是借鉴点。
2、第二点,Ander的解释,就是TypeScript使用了高度函数式编程的特点,没有采用“类”机制。这点与Go其实在思想上,跟Go基于struct、interface的特点有相同之处。如果选择 C#,就必须切换到面向对象的范式,这会增加迁移的阻力,而 Go 则是阻力最小的选择。
从上面两点可以看到,如果一个事情我做到了,可以找千万个理由,因为我做到了!
微软在开发者当中,一直是一个谜团。他们推出了C#,让全世界开发者使用,但他们的主力产品-Windows、Office里面却一直没有使用,而是继续C/C++。隆重推出WPF框架,也只是在Visual Stduio使用了一部分。在很多开发者的心中,如果你自己都不用自己的产品(或还未成熟就由开发一套同类框架),让开发者们如何放心的使用呢?
微软在过去也是一个“始乱终弃”的家伙,也一直有“放弃产品”的“传统”,Windows Phone、SliveLight都是微软的弃子。Go则不同。
一方面go在Google中大量使用,目的就是为了解决Google内部大量C++缓慢的编译速度;另外一方面,在Docker、K8S等非常成功的项目里面,Go已经证明了自己的价值,成为“云原生”时代的基础语言;另一方面是Go精良的设计,在底层和高层特性里面取得了很好的平衡。另外一方面微软的某些做法(对开源也是半遮半掩,爱恨交织),让标志性的“微软语言”-C#让很多公司不敢用,不知道还有其它原因吗?
最新版本:4.2
v4.2 已经于2021年2月末发布,主要更新内容:
更智能的类型别名保护。v4.2 将通过保留一段时间内最初编写和构造的内容来跟踪类型的构造方法,还会跟踪并区分将别名键入其他别名的实例。
元组类型中 rest 元素支持放在任意位置。在v4.2中,rest 元素在使用方式上进行了专门的扩展。在以前的版本中,TypeScript 仅允许 rest 元素位于元组中的最后一个位置。但现在 rest 元素可以在元组中的任何位置出现。唯一的限制是,后面不能存在其他可选元素或 rest 元素。换句话说,每个元组仅一个 rest 元素,rest 元素之后没有可选元素。
interface Clown { /*...*/ }
interface Joker { /*...*/ }
let StealersWheel: [...Clown[], "me", ...Joker[]];
// ~~~~~~~~~~ Error!
// A rest element cannot follow another rest element.
let StringsAndMaybeBoolean: [...string[], boolean?];
// ~~~~~~~~ Error!
// An optional element cannot follow a rest element.
更严格地检查 in 操作符。在 JavaScript 中,在 in 运算符的右侧使用非对象类型是一个运行时错误。现在 v4.2 确保可以在编码时捕获它。
"foo" in 42
// ~~
// error! The right-hand side of an 'in' expression must not be a primitive.
支持 abstract 构造签名。将 abstract 修饰符添加到构造签名表示可以在 abstract 构造函数中传递。这并不会阻止用户传递其他“具体”的类/构造函数,实际上只是表明没有意图直接运行构造函数,因此可以安全地传递任何一种类类型。
abstract class SuperClass {
abstract someMethod(): void;
badda() {}
}
type AbstractConstructor<T> = abstract new (...args: any[]) => T
function withStyles<T extends AbstractConstructor<object>>(Ctor: T) {
abstract class StyledClass extends Ctor {
getStyles() {
// ...
}
}
return StyledClass;
}
class SubClass extends withStyles(SuperClass) {
someMethod() {
this.someMethod()
}
}
支持 --explainFiles 选项。使用此选项时,TypeScript 编译器将给出一些非常冗长的输出,说明文件为何最终进入程序。
通过 --strictNullChecks 选项优化逻辑表达式中的未调用函数检查。
function shouldDisplayElement(element: Element) {
// ...
return true;
}
function getVisibleItems(elements: Element[]) {
return elements.filter(e => shouldDisplayElement && e.children.length)
// ~~~~~~~~~~~~~~~~~~~~
// This condition will always return true since the function is always defined.
// Did you mean to call it instead.
}
可选属性和字符串索引签名之间的规则更加宽松。帮助发现声明缺失。详细内容请查看更新公告。
最新版本:5
v5.0 现已于2023年3月中旬发布。此版本带来了许多新功能,同时旨在使 TypeScript 更小、更简单、更快。实现了新的装饰器标准、更好地支持 Node 和捆绑器中的 ESM 项目的功能、库作者控制泛型推理的新方法、扩展了 JSDoc 功能、简化了配置,并进行了许多其他改进。
自 v5.0 Beta 以来的一个新区别是 TypeScript 允许在 export和export default 之前或之后放置装饰器。这一变化反映了 TC39(ECMAScript/JavaScript 的标准机构)内部的讨论和共识。另一个是新的 bundler 模块解析选项只能在 --module 选项设置为 esnext 时使用。这样做是为了确保在打包器解析之前,输入文件中写入的 import 语句不会转换为 require 调用,无论打包器或加载器是否尊重 TypeScript 的 module 选项。虽然 TypeScript 5.0 Beta 附带了 “在编辑器场景中支持不区分大小写的导入排序” 功能,但版本更新公告中没有详细介绍,因为用于自定义的 UX 仍在讨论中。
自 RC 以来,最显着的变化是 v5.0 现在在 package.json 中指定了 12.20 的最小 Node.js 版本。官方还发布了一篇关于 TypeScript 5.0 向模块迁移的文章。自 v5.0 Beta 和 RC 发布以来,速度基准和包大小增量的具体数字也进行了调整,尽管 noise 一直是运行过程中的一个因素。为了清晰起见,还对一些基准的名称进行了调整,并且包大小的改进已移至单独的图表中。主要功能有如下:
装饰器
const 类型参数
extends 支持多配置文件
enums 类型已成为 Unionenums
--moduleResolution bundler
Resolution Customization Flags
--verbatimModuleSyntax
支持 export type *
JSDoc 支持 @satisfies
JSDoc 支持 @overload
支持使用 --build 传递 Emit-Specific Flags
编辑器中不区分大小写的导入排序
完善 switch/case
速度、内存和包大小优化
破坏性变更和弃用
更多详情可查看发行公告。
v5.2 已于2023年8月下旬正式发布,新特性如下:
using 声明和显式资源管理 (using Declarations and Explicit Resource Management)
装饰器元数据 (Decorator Metadata)
命名和匿名元组元素 (Named and Anonymous Tuple Elements)
为数组并集 (Unions of Arrays) 提供更简单的方法 (Easier Method Usage for Unions of Arrays)
面向对象成员的逗号自动补全 (Comma Completions for Object Members)
优化持续类型兼容性检查 (Ongoing Type Compatibility)
重构内联变量 (Inline Variable Refactoring)
v5.2 实现了即将推出的 ECMAScript 功能,称为装饰器元数据。此功能的关键思想是使装饰器可以轻松地在其使用的任何类上创建和使用元数据。每当使用装饰器函数时,它们现在都可以访问其上下文对象的新 metadata 属性。 metadata 属性仅包含一个简单的对象。由于 JavaScript 允许我们任意添加属性,因此它可以用作由每个装饰器更新的字典。或者由于每个 metadata 对象对于类的每个修饰部分都是相同的,因此它可以用作 Map 的键。在类上或类中的所有装饰器运行后,可以通过 Symbol.metadata 在类上访问该对象。自 v5.2 RC 发布以来,文档添加了 Copying Array Methods,symbols asWeakMap,WeakSetKeys 和 Clickable Inlay Parameter Hints,以及关于始终在声明文件中提示 namespace 关键字的重要更改。更多详情查看发布公告。
v5.6 于2024年9月上旬正式发布,该版本带来了许多新功能和修复,以下是一些主要更新:
语言服务搜索 tsconfig.json 文件的回滚:由于可能导致打开许多引用项目的问题,TypeScript 5.6回滚了beta版本中关于语言服务如何搜索 tsconfig.json 文件的更改。团队正在研究在TypeScript 5.7中重新引入此功能的方法。
类型重命名:BuiltinIterator类型已重命名为IteratorObject。此外,还添加了一些子类型,如ArrayIterator、MapIterator等。
新增 --stopOnBuildErrors 标志:在--build模式下,如果项目构建出现任何错误,将停止继续构建其他项目。
编辑器功能增强:包括对提交字符的直接支持和自动导入的排除模式。
禁止空值和真值检查:TypeScript 5.6 现在会在编译时捕获可能导致意外行为的空值和真值检查。
迭代器辅助方法:引入了对 ECMAScript 提案的支持,为生成器和其他可迭代对象添加了 map、filter、take 等数组方法。
IteratorObject 类型:为了解决原生迭代器和 TypeScript 类型系统之间的冲突,引入了 IteratorObject 类型。
严格的内置迭代器检查:引入了BuiltinIteratorReturn类型和--strictBuiltinIteratorReturn标志,以更严格地检查迭代器的返回类型。
支持任意模块标识符:允许在模块导入中使用字符串字面量作为导入名称。
新增 --noUncheckedSideEffectImports 选项:用于捕获无法解析的副作用导入,避免潜在的拼写错误。
新增 --noCheck 选项:允许跳过所有输入文件的类型检查,以加快构建速度。
允许 --build 模式下的中间错误:在构建模式下,即使依赖项中存在中间错误,也会继续构建项目。
区域优先诊断:在大型文件中,TypeScript现在可以更快地提供诊断信息。
细粒度提交字符:TypeScript 现在为每个自动完成项提供自己的提交字符,使得编辑器可以更智能地自动完成代码。
自动导入排除模式:允许通过正则表达式模式排除某些自动导入建议。
v5.8 已于2025年3月上旬正式发布。主要变化如下:
条件和索引访问类型的返回检查:增强函数返回类型的检查,确保条件类型和索引访问类型的分支明确,减少运行时错误。
支持在 --module nodenext 下使用 require() 加载 ECMAScript 模块:允许 CommonJS 文件通过 require() 加载 ESM 文件,适用于 Node.js 22+。
--module node18 标志稳定:提供稳定的模块解析行为,禁用 require() ESM 并支持导入断言(已弃用,推荐使用导入属性)。
新增 --erasableSyntaxOnly 选项:确保只使用可擦除的语法(如 enum、namespace 不含运行时代码),与 Node.js 23.6+ 的 --experimental-strip-types 兼容。
新增 --libReplacement 标志:允许禁用默认 lib 文件替换,提供更多自定义选项。
声明文件中保留计算属性名:确保计算属性名在声明文件中一致,可能影响索引签名和隔离声明。
程序加载和更新的优化:改进路径规范化、缓存选项验证,提升大项目和 --watch 模式的性能。
导入断言限制:在 --module nodenext 中,使用 with 替代 assert。
lib.d.ts 更新:可能影响 DOM 类型检查。
更多详情查看发行公告。
官方主页:
http://www.typescriptlang.org/
https://www.tslang.cn/

TypeScript是为开发大型应用而设计的,并且其可转译成JavaScript。由于TypeScript是JavaScript的严格超集,任何现有的JavaScript程序都是合法的TypeScript程序。支持为现存JavaScript库添加类型信息的定义文件,方便其他程序像使用静态类型的值一样使用现有库中的值。目前有第三方提供常用库如jQuery、MongoDB、Node.js和D3.js的定义文件。编译器本身也是用TypeScript编写,并被转译为JavaScript,以Apache许可证第二版发布。
与JavaScript 相比,进步的地方包括:加入注释,让编译器理解所支持的对象和函数,编译器会移除注释,不会增加开销;增加一个完整的类结构,使之成为一个全新的面向对象语言。
语言特性
TypeScript是一种给JavaScript添加特性的语言扩展。增加的功能包括:
类型批注和编译时类型检查
类型推断
类型擦除
接口
枚举
Mixin
泛型编程
名字空间
元组
Await
以下功能是从ECMA 2015反向移植而来:
类
模块
lambda函数的箭头语法
可选参数以及默认参数
在语法上,TypeScript很类似JScript .NET,它是另外一个微软对ECMA-262语言标准的实现,添加了对静态类型、经典的面向对象语言特性(如类、继承、接口和名字空间等)的支持。
示例代码:
class Greeter {
constructor(public greeting: string) { }
greet() {
return "" + this.greeting + "";
}
};
var greeter = new Greeter("Hello, FreeOA!");
var str = greeter.greet();
document.body.innerHTML = str;
始于JavaScript,归于JavaScript
TypeScript从今天数以百万计的JavaScript开发者所熟悉的语法和语义开始。使用现有的JavaScript代码,包括流行的JavaScript库,并从JavaScript代码中调用TypeScript代码。它可以编译出纯净、 简洁的JavaScript代码,并且可以运行在任何浏览器上、Node.js环境中和任何支持ECMAScript 3(或更高版本)的JavaScript引擎中。
强大的工具构建 大型应用程序
类型允许JavaScript开发者在开发JavaScript应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构。类型是可选的,类型推断让一些类型的注释使你的代码的静态验证有很大的不同。类型让你定义软件组件之间的接口和洞察现有JavaScript库的行为。
先进的 JavaScript
TypeScript提供最新的和不断发展的JavaScript特性,包括那些来自2015年的ECMAScript和未来的提案中的特性,比如异步功能和Decorators,以帮助建立健壮的组件。这些特性为高可信应用程序开发时是可用的,但是会被编译成简洁的ECMAScript3(或更新版本)的JavaScript。
TypeScript 编程语言团队于2021年3月10日宣布已重写 TypeScript 手册,该手册是学习 TypeScript 语言及其常用用法的主要资源。新手册在团队中已经是一个运行多年的项目,包含了大大小小的数百个贡献。据团队的说法,其在过去的一年里扩大了文档的规模、现代化程度以及范围。现在该手册是 TypeScript 语言文档中最重要的部分。重写工作的重点在于对 TypeScript 的教学方式进行了几处更改。包括省去讲授 JavaScript(因为网络上和相关书籍资源已经非常丰富了)、渐进式教学、每当发布新的 TypeScript 版本时提供最新的代码示例,以及编写日常用例。通过专注于这些领域,团队可以为 TypeScript 语言提供更加集中和简单易懂的介绍。 官方表示,在阅读该手册之后,开发人员应该能够阅读和理解常用的 TypeScript 语法和模式,解释编译器选项的效果以及预测大多数用例的类型系统行为。
阅读新手册:Web / Epub / PDF
《TypeScript 教程》是一份由阮一峰所编译的TypeScript开源教程,介绍基本概念和用法,面向初学者。阮表示在2023年3月份快写完这份教程的时候,TypeScript 5.0 突然发布了。装饰器(Decorators)改用全新语法。因此他重写了这一章,于是装饰器现在就有新语法和旧语法两章,因为 TypeScript 同时支持这两者。亦可参见Github开源地址。
用于微型物联网设备的DeviceScript
DeviceScript 为基于低资源微控制器的设备带来了专业的 TypeScript 开发人员体验。其被编译为自定义 VM 字节码,可以在非常受限的环境中运行,采用MIT协议授权。特性如下:
TypeScript for IoT
熟悉的语法和工具,尽在你的指尖。
Small Runtime
低功耗 / 闪存 / 内存的字节码解释器。
Hardware as Services
传感器和执行器的客户端 / 服务器架构。
Debugging
在 Visual Studio Code 中,用于嵌入式硬件或模拟设备。
Simulation and Testing
使用硬件 / 模拟传感器开发和测试你的固件。CI 友好。
Development Gateway
具有设备管理、固件部署和消息队列的 Prototype cloud service。
为性能考量将编译器和工具链将移植到 Go
TypeScript、C#、Delphi 语言之父 Anders Hejlsberg 于2025年3月中旬在 Microsoft 开发者博客宣布重大消息:TypeScript 编译器以及工具链将移植到 Go 语言,性能提升高达 10 倍!
这一举动旨在解决 TypeScript 在大型代码库中性能瓶颈的问题,为开发者带来更流畅、更高效的开发体验。根据官方公布的数据,新的原生实现将带来以下惊人的改进:
1.编辑器启动的项目加载速度提升 8 倍
2.大多数构建时间缩短 10 倍
3.内存使用量大幅减少
通过移植当前代码库,预计能够在2025年中期预览能够进行命令行类型检查的tsc的原生实现,并在年底前提供用于项目构建和语言服务的功能完整解决方案。可以从我们新的工作仓库构建和运行Go代码,该仓库与现有TypeScript代码库采用相同的许可证提供。查看README获取有关如何构建和运行tsc和语言服务器的说明,以及查看目前已实现功能的摘要。随着新功能可供测试,我们将定期发布更新。以下是在GitHub上运行tsc对不同大小的一些流行代码库的时间:

Anders Hejlsberg 和 TypeScript 团队在 GitHub 仓库的讨论区解释了为何采用 Go,主要原因有以下几点:
1.代码结构相似性:TypeScript 现有代码库采用函数式编程风格,很少使用类。而 Go 语言也以函数和数据结构为中心,与现有代码结构高度相似,这使得移植工作更加容易。
2.内存管理:Go 语言提供自动垃圾回收(GC),无需开发者手动管理内存,这大大简化了移植过程,降低了代码复杂度。同时,Go 的 GC 对 TypeScript 编译器这类批处理任务影响很小。
3.内存布局控制:Go 语言允许对内存布局和分配进行精细控制,这对于优化性能至关重要。
4.图处理能力:TypeScript 编译器涉及大量的树遍历和多态节点处理,Go 语言在这方面表现出色。
Anders Hejlsberg 强调,这是一次 “移植” 而非 “重写”,目标是尽可能保留现有代码库的结构和语义,确保兼容性。Go 语言的特性与 TypeScript 现有代码库的契合度最高,是 “阻力最小” 的路径。最近的TypeScript版本是TypeScript v5.8,v5.9即将推出。基于JS的代码库将继续开发到6.x系列,v6.0将引入一些弃用和破坏性变更,以与即将推出的原生代码库保持一致。当原生代码库达到与当前TypeScript足够的对等性时将发布它作为v7.0。这仍在开发中,将在稳定性和功能里程碑发生时宣布。为了清晰起见,我们将简单地将它们称为TypeScript 6(JS)和TypeScript 7(原生),因为这将是可预见未来的命名法。在内部讨论或代码注释中,您可能还会看到我们提到"Strada"(原始TypeScript代号)和"Corsa"(此项工作的代号)。
为什么微软不用自己的C#来做这个事情,而是用了Google的Go语言?
其实这跟微软的传统有关。我们知道微软一直是操作系统和编程语言的“大厂”,Windows和Visual Studio都世界闻名。同时微软也有一个传统,叫“Eat Dog Food”。这里的“吃狗粮”,不是吃恋爱的狗粮,看见对面拥抱亲亲就想看死对面的那种,而是微软内部就使用开发中的Windows作为平台,再使用自家的编程工具(VC、C#)来编写软件。
在使用的过程中,把遇到的问题反馈到公司内部的开发小组,让他们持续改进。因为是内部沟通,成本很低,速度很快。这也是微软早期的成功秘诀之一。
那这次为什么TypeScript没有用C#,而是用Go呢?
其实有一个采访,TypeScript的作者之一,著名的“Delphi之父”-Anders出面说明了这个问题。原因据说有2个:
1、Go其实比C#更加底层,更接近原生。但是同时Go还具有GC-“内存自动回收”这个超级大利器。而C#是一种“IL”语言,需要NetCore平台的支持,相比较Go无敌的“跨平台编译只需要改变一个变量”的机制还有相当大的差距。这一点,其实是Go吸取了Plan9的优点。Plan9作为Unix发明者开发的下一代“改良平台”,虽然不是很成功,但是其中的很多思想是非常先进的。而同为Plan9开发者的开发的Go,其实从Plan9吸取了很多东西,包括其特殊使用的跨平台编译器,channel机制,无疑都是借鉴点。
2、第二点,Ander的解释,就是TypeScript使用了高度函数式编程的特点,没有采用“类”机制。这点与Go其实在思想上,跟Go基于struct、interface的特点有相同之处。如果选择 C#,就必须切换到面向对象的范式,这会增加迁移的阻力,而 Go 则是阻力最小的选择。
从上面两点可以看到,如果一个事情我做到了,可以找千万个理由,因为我做到了!
微软在开发者当中,一直是一个谜团。他们推出了C#,让全世界开发者使用,但他们的主力产品-Windows、Office里面却一直没有使用,而是继续C/C++。隆重推出WPF框架,也只是在Visual Stduio使用了一部分。在很多开发者的心中,如果你自己都不用自己的产品(或还未成熟就由开发一套同类框架),让开发者们如何放心的使用呢?
微软在过去也是一个“始乱终弃”的家伙,也一直有“放弃产品”的“传统”,Windows Phone、SliveLight都是微软的弃子。Go则不同。
一方面go在Google中大量使用,目的就是为了解决Google内部大量C++缓慢的编译速度;另外一方面,在Docker、K8S等非常成功的项目里面,Go已经证明了自己的价值,成为“云原生”时代的基础语言;另一方面是Go精良的设计,在底层和高层特性里面取得了很好的平衡。另外一方面微软的某些做法(对开源也是半遮半掩,爱恨交织),让标志性的“微软语言”-C#让很多公司不敢用,不知道还有其它原因吗?
最新版本:4.2
v4.2 已经于2021年2月末发布,主要更新内容:
更智能的类型别名保护。v4.2 将通过保留一段时间内最初编写和构造的内容来跟踪类型的构造方法,还会跟踪并区分将别名键入其他别名的实例。
元组类型中 rest 元素支持放在任意位置。在v4.2中,rest 元素在使用方式上进行了专门的扩展。在以前的版本中,TypeScript 仅允许 rest 元素位于元组中的最后一个位置。但现在 rest 元素可以在元组中的任何位置出现。唯一的限制是,后面不能存在其他可选元素或 rest 元素。换句话说,每个元组仅一个 rest 元素,rest 元素之后没有可选元素。
interface Clown { /*...*/ }
interface Joker { /*...*/ }
let StealersWheel: [...Clown[], "me", ...Joker[]];
// ~~~~~~~~~~ Error!
// A rest element cannot follow another rest element.
let StringsAndMaybeBoolean: [...string[], boolean?];
// ~~~~~~~~ Error!
// An optional element cannot follow a rest element.
更严格地检查 in 操作符。在 JavaScript 中,在 in 运算符的右侧使用非对象类型是一个运行时错误。现在 v4.2 确保可以在编码时捕获它。
"foo" in 42
// ~~
// error! The right-hand side of an 'in' expression must not be a primitive.
支持 abstract 构造签名。将 abstract 修饰符添加到构造签名表示可以在 abstract 构造函数中传递。这并不会阻止用户传递其他“具体”的类/构造函数,实际上只是表明没有意图直接运行构造函数,因此可以安全地传递任何一种类类型。
abstract class SuperClass {
abstract someMethod(): void;
badda() {}
}
type AbstractConstructor<T> = abstract new (...args: any[]) => T
function withStyles<T extends AbstractConstructor<object>>(Ctor: T) {
abstract class StyledClass extends Ctor {
getStyles() {
// ...
}
}
return StyledClass;
}
class SubClass extends withStyles(SuperClass) {
someMethod() {
this.someMethod()
}
}
支持 --explainFiles 选项。使用此选项时,TypeScript 编译器将给出一些非常冗长的输出,说明文件为何最终进入程序。
通过 --strictNullChecks 选项优化逻辑表达式中的未调用函数检查。
function shouldDisplayElement(element: Element) {
// ...
return true;
}
function getVisibleItems(elements: Element[]) {
return elements.filter(e => shouldDisplayElement && e.children.length)
// ~~~~~~~~~~~~~~~~~~~~
// This condition will always return true since the function is always defined.
// Did you mean to call it instead.
}
可选属性和字符串索引签名之间的规则更加宽松。帮助发现声明缺失。详细内容请查看更新公告。
最新版本:5
v5.0 现已于2023年3月中旬发布。此版本带来了许多新功能,同时旨在使 TypeScript 更小、更简单、更快。实现了新的装饰器标准、更好地支持 Node 和捆绑器中的 ESM 项目的功能、库作者控制泛型推理的新方法、扩展了 JSDoc 功能、简化了配置,并进行了许多其他改进。
自 v5.0 Beta 以来的一个新区别是 TypeScript 允许在 export和export default 之前或之后放置装饰器。这一变化反映了 TC39(ECMAScript/JavaScript 的标准机构)内部的讨论和共识。另一个是新的 bundler 模块解析选项只能在 --module 选项设置为 esnext 时使用。这样做是为了确保在打包器解析之前,输入文件中写入的 import 语句不会转换为 require 调用,无论打包器或加载器是否尊重 TypeScript 的 module 选项。虽然 TypeScript 5.0 Beta 附带了 “在编辑器场景中支持不区分大小写的导入排序” 功能,但版本更新公告中没有详细介绍,因为用于自定义的 UX 仍在讨论中。
自 RC 以来,最显着的变化是 v5.0 现在在 package.json 中指定了 12.20 的最小 Node.js 版本。官方还发布了一篇关于 TypeScript 5.0 向模块迁移的文章。自 v5.0 Beta 和 RC 发布以来,速度基准和包大小增量的具体数字也进行了调整,尽管 noise 一直是运行过程中的一个因素。为了清晰起见,还对一些基准的名称进行了调整,并且包大小的改进已移至单独的图表中。主要功能有如下:
装饰器
const 类型参数
extends 支持多配置文件
enums 类型已成为 Unionenums
--moduleResolution bundler
Resolution Customization Flags
--verbatimModuleSyntax
支持 export type *
JSDoc 支持 @satisfies
JSDoc 支持 @overload
支持使用 --build 传递 Emit-Specific Flags
编辑器中不区分大小写的导入排序
完善 switch/case
速度、内存和包大小优化
破坏性变更和弃用
更多详情可查看发行公告。
v5.2 已于2023年8月下旬正式发布,新特性如下:
using 声明和显式资源管理 (using Declarations and Explicit Resource Management)
装饰器元数据 (Decorator Metadata)
命名和匿名元组元素 (Named and Anonymous Tuple Elements)
为数组并集 (Unions of Arrays) 提供更简单的方法 (Easier Method Usage for Unions of Arrays)
面向对象成员的逗号自动补全 (Comma Completions for Object Members)
优化持续类型兼容性检查 (Ongoing Type Compatibility)
重构内联变量 (Inline Variable Refactoring)
v5.2 实现了即将推出的 ECMAScript 功能,称为装饰器元数据。此功能的关键思想是使装饰器可以轻松地在其使用的任何类上创建和使用元数据。每当使用装饰器函数时,它们现在都可以访问其上下文对象的新 metadata 属性。 metadata 属性仅包含一个简单的对象。由于 JavaScript 允许我们任意添加属性,因此它可以用作由每个装饰器更新的字典。或者由于每个 metadata 对象对于类的每个修饰部分都是相同的,因此它可以用作 Map 的键。在类上或类中的所有装饰器运行后,可以通过 Symbol.metadata 在类上访问该对象。自 v5.2 RC 发布以来,文档添加了 Copying Array Methods,symbols asWeakMap,WeakSetKeys 和 Clickable Inlay Parameter Hints,以及关于始终在声明文件中提示 namespace 关键字的重要更改。更多详情查看发布公告。
v5.6 于2024年9月上旬正式发布,该版本带来了许多新功能和修复,以下是一些主要更新:
语言服务搜索 tsconfig.json 文件的回滚:由于可能导致打开许多引用项目的问题,TypeScript 5.6回滚了beta版本中关于语言服务如何搜索 tsconfig.json 文件的更改。团队正在研究在TypeScript 5.7中重新引入此功能的方法。
类型重命名:BuiltinIterator类型已重命名为IteratorObject。此外,还添加了一些子类型,如ArrayIterator、MapIterator等。
新增 --stopOnBuildErrors 标志:在--build模式下,如果项目构建出现任何错误,将停止继续构建其他项目。
编辑器功能增强:包括对提交字符的直接支持和自动导入的排除模式。
禁止空值和真值检查:TypeScript 5.6 现在会在编译时捕获可能导致意外行为的空值和真值检查。
迭代器辅助方法:引入了对 ECMAScript 提案的支持,为生成器和其他可迭代对象添加了 map、filter、take 等数组方法。
IteratorObject 类型:为了解决原生迭代器和 TypeScript 类型系统之间的冲突,引入了 IteratorObject 类型。
严格的内置迭代器检查:引入了BuiltinIteratorReturn类型和--strictBuiltinIteratorReturn标志,以更严格地检查迭代器的返回类型。
支持任意模块标识符:允许在模块导入中使用字符串字面量作为导入名称。
新增 --noUncheckedSideEffectImports 选项:用于捕获无法解析的副作用导入,避免潜在的拼写错误。
新增 --noCheck 选项:允许跳过所有输入文件的类型检查,以加快构建速度。
允许 --build 模式下的中间错误:在构建模式下,即使依赖项中存在中间错误,也会继续构建项目。
区域优先诊断:在大型文件中,TypeScript现在可以更快地提供诊断信息。
细粒度提交字符:TypeScript 现在为每个自动完成项提供自己的提交字符,使得编辑器可以更智能地自动完成代码。
自动导入排除模式:允许通过正则表达式模式排除某些自动导入建议。
v5.8 已于2025年3月上旬正式发布。主要变化如下:
条件和索引访问类型的返回检查:增强函数返回类型的检查,确保条件类型和索引访问类型的分支明确,减少运行时错误。
支持在 --module nodenext 下使用 require() 加载 ECMAScript 模块:允许 CommonJS 文件通过 require() 加载 ESM 文件,适用于 Node.js 22+。
--module node18 标志稳定:提供稳定的模块解析行为,禁用 require() ESM 并支持导入断言(已弃用,推荐使用导入属性)。
新增 --erasableSyntaxOnly 选项:确保只使用可擦除的语法(如 enum、namespace 不含运行时代码),与 Node.js 23.6+ 的 --experimental-strip-types 兼容。
新增 --libReplacement 标志:允许禁用默认 lib 文件替换,提供更多自定义选项。
声明文件中保留计算属性名:确保计算属性名在声明文件中一致,可能影响索引签名和隔离声明。
程序加载和更新的优化:改进路径规范化、缓存选项验证,提升大项目和 --watch 模式的性能。
导入断言限制:在 --module nodenext 中,使用 with 替代 assert。
lib.d.ts 更新:可能影响 DOM 类型检查。
更多详情查看发行公告。
官方主页:
http://www.typescriptlang.org/
https://www.tslang.cn/