【CSDN 编者按】TypeScript 算是一种编程语言吗?来看看你是否真的了解TypeScript 和 JavaScript 的区别以及它的使用场景。
原文链接:https://chrlschn.dev/blog/2023/09/typescript-is-not-a-programming-language/#understanding-type-vs-shape
未经允许,禁止转载!
最近,一个 Mastodon 帖子让我陷入沉思,我在想为什么 TypeScript 成为了一些开发人员难以采用的语言。
我的结论是,它从名字开始:“TypeScript”,人们就误解它只是静态类型的 JavaScript。
但实际上,它不是。
不将 TypeScript 视为一种编程语言甚至类型系统可能更容易。事实上,了解 TypeScript 的最简单方法就是将其视为一种形状定义语言。
了解类型与形状
关于这一点的一个简单示例是以下代码片段:
在第 12 行,我们向函数描述了参数 req 的形状。
当我们运行这段代码时,我们可以看到它的行为完全符合预期:
从第 12 行的函数定义可以看出,TypeScript 并不是一个类型系统,它实际上是一个形状定义系统(或者更正式地说,是一个结构类型系统)。
如果我们看一下 JavaScript:
很明显,这样做是可行的。你可以看到,在输出的 JavaScript 中,TypeScript 消失了。这是因为 TypeScript 的唯一目的是告知编译器和开发时语言服务器有关有效形状的信息。事实上,Node 和浏览器都不运行 TypeScript;他们只解析 JavaScript。
TypeScript 仍然是“鸭子类型”
当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。
上面代码片段的一个变体可能有助于进一步强调这一点:
请注意第 12 行的微妙变化:我们将函数描述为需要一个形状类似于 Req 类型的参数 req,但该函数会很乐意接受接口 Req2 的对象,因为 TypeScript 不是类型系统。在 C# 等静态类型语言中,尽管形状匹配,但类型元数据不匹配,所以这将失败(我们仍然可以在 C# 和 Java 等静态类型语言中通过定义接口或抽象基类等类型契约来实现此目的) 。
考虑到这一点,许多其他实用类型和奇怪的“类型体操”就有意义了:它们都是描述形状的简单方式——通常是在其他现有形状的背景下。
TypeScript 实用函数
为了进一步强调这一点,请考虑以下使用实用程序类型 Omit<> 的示例:
或者,使用实用程序类型 Pick<> 进行逆操作:
每一种都只是描述有效形状的不同方式。
TypeScript 泛型
即使我们添加泛型类型约束(第 13 行),原理依旧是一样的:
交叉类型
即使这个使用交集类型的构造也可以:
结语
如果你是一名正在使用 TypeScript 的开发人员,那么你要做的第一件事可能就是忽略名称中的 “Type” 部分,或许将其视为 “ShapeDef” ;你在开发时向语言服务器、编译时向编译器描述有效的形状,以及为了您的开发团队同事的理智。TypeScript 不是静态类型编程语言,而是具有形状定义的 JavaScript。
第二件事是拿起 Adam Freeman 的 Essential TypeScript 书。这无疑是我拥有的最好的技术书籍之一,对于任何想要做好 TypeScript 的开发人员来说都是一本很棒的书。
我希望从这些简短的示例中可以清楚地看出,将 TypeScript 视为一种编程语言或静态类型系统,最终会给理解如何使用这种形状定义系统编写更安全的 JavaScript 造成心理障碍。