概述
本文是对 https://github.com/Microsoft/TypeScript/issues/4789 的翻译。后续文章译者会持续跟进后续进展并给出自己的评论。
术语定义
此文章用到了不少专业术语,为了阅读方便,罗列部分关键术语如下:
- 智能感知:指的是IDE代码提示、重构等技术的底层架构支持
- 基于可执行程序的智能感知:译者猜测应该指一种使用独立运行程序(exe)来实现的智能感知系统。
- JavaScript 语言服务:一种微软开发的基于可执行程序的智能感知,被应用于 Visual Studio中。
- TypeScript 语言服务:TypeScript的一个模块,实现功能类似 JavaScript语言服务,依托于 TypeScript 类型系统,并不基于可执行程序。
- 库定义文件:指的是 TypeScript Definition File,即 .d.ts 文件
通过 TypeScript 完善 JavaScript
这个方案概述了通过使用和扩展 TypeScript 的能力,从而提供完善的JavaScript开发体验。
当前问题
-
JavaScript 智能感知在如今是一个大杂烩。不同的产品的体验有很大区别,并且经常是不一致或者不准确的。比如:
基于可执行程序( Execution )的智能感知会在大量动态代码中失效(比如代码依赖于一个外部资源或者用户交互),行为会在不同的硬件上不同(因为达到了可执行程序的超时限制),并且是不可预知的(有时候是否可以正常工作取决于看似无关的编辑)
静态分析引擎会进行深度代码分析,比如跟踪调用地点和条件分支,这通常会消耗大量的资源(特别是大型代码库)并且需要大量的代码去维护和适配各种在长尾的类库和模块中用到的 JavaScript 模式。
-
类型支持是 TypeScript 中很棒的特性,并且提供了准确且一致的智能感知。但是很多开发者想继续直接编写 JavaScript 代码,或者不想在他们已经存在的 JavaScript 项目中 处理所有的 TypeScript 错误。因此:
一些最好的 JavaScript 类库已经拥有了 TypeScript 库定义文件。但这对 JavaScript 开发者来说是无法使用的。
即使他们想把项目移植到 TypeScript 上也有很大的挑战。如果只是简单的把 .js 文件改名为 .ts 文件,会遭遇很多 TypeScript语法错误。
类型在 JavaScript 中可以通过其他方式建模,比如 JSDoc注释格式。但是 IDE 支持和现存类库的建模方式是�参差不齐的。
-
当前版本的 Visual Studio 对 JavaScript 的支持很差,对开发来说并不是一流的体验。
基于可执行程序的JavaScript 语言服务,基于分析引擎的 Node Tools for Visual Studio ,拥有一个静态类型系统的 TypeScript 工具,当在这些项目类型中编写代码时,上述内容并没有集成起来。
除了不能跨越上下文理解代码之外,这会导致不同的编码体验,比如 ES6 语法支持,自动格式化,智能感知行为等等。这三种方式都彼此略有不同。(更不用说这在编写新特性、修复BUG时需要在三种实现中带来很多重复的工作量)
机会
如果 TypeScript语言服务可以增强 JavaScript 开发体验的话:
TypeScript 生态系统中提供的大量库定义是可以被利用的,可以为这些类库提供丰富的智能感知。
许多基于可执行程序或者分析引擎的智能感知系统的挑战可以被避免。(还是有一些会出现,下文会进一步概述)
通过在 JavaScript 中利用 TypeScript的类型定义, TypeScript 可以理解(在某种程度上)JavaScript代码。
这提供了一种在一个项目中混合编写 TypeScript 和 JavaScript 代码的能力,并且可以在必要的情况下逐步迁移既有的 JavaScript 代码。
TypeScript 将 ES6+ 结构(比如类,箭头函数,模块等等)编译成 ES5代码的能力可以应用到 JavaScript 中。(允许编写 JavaScript ES6代码并运行在 ES5的引擎中)。这也适合于其他的 TypeScript特性(比如提供了通过 TypeScript TSX来提供对 JSX 的支持)
不同项目类型的代码可以共享上下文(比如支持 ES5的浏览器中的代码可以理解使用ES6编写的Node模块,并且都可以利用 TypeScript 接口定义)。
编码体验和设置是一致的(以 Visual Studio 为例,不再需要付出维护三套实现的工程成本,取而代之的是只改善其中一个)。
基于当前 TypeScript代码库可以让 JavaScript开发体验脱离出 VisualStudio。( TypeScript语言服务可以被非常简单的应用在其他地方,比如 Sublime 插件,VS Code编辑器等)
挑战
如何在 JavaScript 内声明和使用类型(比如 JSDoc,lib.d.ts , node.d.ts ,第三方库定义,定制代码,类型推论,等等)
如何支持一些在 TypeScript 中现在不支持的通用 JavaScript 模式。(比如 RequireJS和 CommonJS 模块,构造函数和原型属性等等)
如何将 JavaScript 提供给 TypeScript 编译过程中(比如那些文件需要被选取,编译器参数等)
假设上述问题可以解决,由此产生的 JavaScript 开发者体验( 比如让 TypeScript 对只对JavaScript感兴趣的开发者透明,当类型推断失败时候的智能感知体验,对不同的项目类型设置不同的示例项目结构和设置,如何混合代码或者集成到现有代码中。
上述挑战会在下面的内容中单独的提及到。
JavaScript types in TypeScript
JavaScript module systems in TypeScript
JavaScript in TypeScript compilations
JavaScript developer experience