【翻译转载】TypeScript 被高估了

发布时间 2023-11-28 17:32:57作者: Truraly

为什么 JavaScript 可能仍然是你最好的选择。

原文链接
作者标题

TypeScript 语言于 2012 年发布。刚发布时只是一个 JavaScript 超集。但几年后,它开始以过度炒作的速度爆炸式地增长。

它确实给 JavaScript 生态系统带来了一些有用的功能。然而,仅凭这些优点就足以让我们 all in Ts 吗?Ts 是否存在一些没人讨论的缺点?你是否应该关心这些缺点?

如果你想在项目中使用 Ts,我建议你阅读我的建议后再重新考虑是否要使用 Ts。本文将列出最值得考虑的 5 个 Ts 的缺点。

从 2021 年 Github Octoverse 报告中捕获

1.使你的代码混乱

在 JS 中,通过使用更清晰的参数和方法名称,我们的代码库应该已经是非常明确的了。我们不需要任何虚拟类型检查。

但使用 TypeScript 时,Ts 会导致很多冗余的内容。

下面是一个例子:


const sum = (a, b) => a + b;

如果我们将其移植到 TypeScript,它将变为:


const sum = (a: number, b: number): number => (a + b) as number;

Ts 比 JS 阅读和理解都要困难得多。没有足够的 TypeScript 知识,Ts 将会变得难以理解。Ts 是异类,并且不赏心悦目。(其实我觉得很好看)

这导致了一个结果:开发人员现在突然需要理解一种新的语言。并且在你编写代码时,编辑器将占用更多的 CPU 资源来对代码提供帮助。

2.浏览器支持性差

浏览器并不支持原生的 Ts 代码。虽然微软提出过一个针对的提案,但这个提案仍然在早期阶段,你可以点击这里 查阅

这意味着什么?无论如何我们最后都要运行 JS 代码,那我们花精力去使用 Ts 的目的是什么?我们需要在项目中添加很多额外的步骤,而结果仍然 JS 代码,这个决定看起来十分不理智。

如果微软能将那个提案变成现实,那么这种说法值得参考。尽管如此,我们仍然需要等待浏览器能良好地支持 Ts 代码。

3.非常多的配置选项

在使用 Ts 前,我们需要配置相当多的选项。我们需要掌握tsconfig.json的使用方法。

运行下面的代码来初始化一个 ts 项目


# install TypeScript globally

# 安装Ts依赖

npm install -g typescript

# init project

# 初始化Ts项目

tsc --init

package.json中的部分设定:

  • compilerOptions:最主要的配置选项,包含了代码如何工作的选项。其中包含:格式检查,模块,发行,编辑器支持……这是我们花费最多时间来配置的地方

  • include files:包含的文件名或者模式数组

  • exclude files:不包含的文件名或者模式数组

当我们配置完tsconfig文件,还不能马上运行 Ts 代码。我们需要配置一个 Webpack 加载器来打包我们的 Ts 代码。你会纠结于选择 Babel 还是 ts-loader 来打包你的代码。于是这件事便愈发复杂了。

除此之外,我们还需要不断更新我们的 Ts 代码库。每一个版本都会有大量不同的更新。这意味着我们要花费相当多的时间在这些大约 4 个月就会产生一次的更新上

4.陡峭的学习路线(Steep Learning Curve)

Ts 比 JS 更加复杂,需要花费一些时间来适应和掌握。下面是一些 Ts 的新特新:

  • 映射类型

  • 元组(Tuples)

  • 类型推断(Inference)

  • 模板字符串(Template Literals)~(这不是 js 的吗?)~

  • 函数重载

  • 联合类型(Unions)eg:number | string

  • 泛型(Generics)

Ts 的一些特性比较难以理解。不同于其他特性,它们产生了一些比较奇怪的 JS 代码。比如 enum,JS 里并没有这样的特性。

下面是展示的代码。


enum Status {

  Succes,

  Error,

  Warning,

  Info

}

对于 JS 使用者而言,这个特性会花费他们不少时间去掌握。~(我寻思 enum 用得也不多啊)~

此外,Ts 会产生下面的 JS 代码:


var Status;

(function (Status) {

  Status[(Status["Succes"] = 0)] = "Succes";

  Status[(Status["Error"] = 1)] = "Error";

  Status[(Status["Warning"] = 2)] = "Warning";

  Status[(Status["Info"] = 3)] = "Info";

})(Status || (Status = {}));

上面的代码看上去有点冗余,我们在写 Ts 时需要注意这些类似的问题。但这增加了我们工作的复杂性。

5.与第三方的兼容性

一些第三方库不完全支持 Ts,有时候是完全不支持,编写者没有理由这么做。但这导致 Ts 的我们会使用未经检查的代码,这破坏了 Ts 的原则。

这还不是最糟的,有时候我们会遇见一些支持但不完全支持 Ts 的库,或者一些前后矛盾的接口。这让我们的工作更加艰难和麻烦。我们该如何相信第三方的 Ts 功能?

幸运的是,我们可以使用 DefinitelyTyped 包社区,这是一个高质量的 Ts 类似的仓库,它可以一定程度上解决这个问题。如果你尝试使用它,你会发现你经常打开 PRs 去解决一些可能发生的问题。

6. 影响开发速度

高效是开发的一个重要方面。Ts 各种问题导致我们背负了一个"TypeScript 负担"。这严重影响了我们的开发效率,让我们的开发工作变得更不敏捷和更拘谨。这也是 JS 不使用类型检查的原因。

很多支持者说 Ts 能帮助避免很多恶性 BUG。然而,Ts 给予了anyFunction这 2 个宽泛的类型,并且你可以使用@ts-ignore来逃过类型检查。这导致了 Ts 代码不一定那么可信。

那么,如何才能确保我们代码的健壮性,减少 bug 的产生?

只有通过大量的测试,才能让我们的代码在更极端的情况下仍然健壮。

同时,Ts 的编译器也会拖累我们,ESBuild 或者 SWC 能更快地完成这个流程。但是,大多数人都是用 Webpack。我们可以使用 Bable 代替 Webpack 来提升打包速度。但是这个速度是牺牲类型换来的,这会导致在编译时无法报出类型的错误,但这个错误可能在运行出现。

最后

我希望这篇文章能减少你的偏见,Ts 是一个优秀的语言,但是现在被过度炒作了

你可以继续在复杂的项目中使用 Ts,当你的团队也掌握 Ts 时,Ts 可能会展现它的优势。

但是,对于小型的应用(Minimum Viable Product)或项目,我建议你拒绝 Ts。因为随着 DDL 的靠近,一个未被完全证实有用的工具可能会给你的团队造成不小的麻烦。