不,TypeScript 不是 JavaScript 的 OOP 版本
我经常听到的关于 TypeScript 的常见误解是 - TypeScript 比 JavaScript 更面向对象,TypeScript 更像 Java、C#,是为面向对象程序员制作的,它强调类和继承。
最后一个关于这种误解的例子,来自一篇非常受欢迎的文章—— 《TypeScript 教程:一步一步教你学习 TypeScript》。以下是文章的摘录:
TypesScript 是一种面向对象的编程语言,而 JavaScript 是一种脚本语言
在 dev.to 上关于 TypeScript 的一篇热门文章中,竟然出现了如此错误的论断😔。我决定反驳💪这些说法,并向你证明 TypeScript 并不比 JS 本身更面向对象。
TS 具有类和继承,因此它更加面向对象
TypeScript 有类,JavaScript 也有。看一下
// JS🟨
class User {
#name
constructor(name) {
this.#name = name;
}
}
const user = new User('Tom');
TS 中的相同部分
// TS🟦
class User {
#name: string
constructor(name: string) {
this.#name = name;
}
}
const user = new User('Tom')
和额外的类型注解有什么区别吗?我想没有。你注意到私有字段了吗?是的,它们在两个版本中都有,因为私有字段已经进入了ECMAScript 标准的第 3 阶段。
遗产
就两者而言,考虑
// JS🟨 and TS🟦
class Admin extends User{
#type = 'admin'
}
const admin = new Admin('Tom');
上面的 TS 版本是什么?一样……是的,多亏了类型推断,我一点都不需要改。那么区别在哪里呢?没有区别。
TypeScript 类型系统强调 OOP
确实,TypeScript 有接口的概念,对于使用 Java 或 C# 等静态类型面向对象语言的人来说,这个概念很熟悉。但 TypeScript 也有其他类型的语法,而且它基于代数数据类型,这在函数式语言中很常见。
而不是使用interface
和extends
interface X extends Y {x: number}
您可以使用type
和交集运算符&
type X = Y & {x: number}
您会得到相同的结果!
查看以下相同类型定义的两个等效版本
{
// interface version - familiar for Java/C#
interface User {
type: string
name: string
}
interface Admin extends User {
type: 'admin'
}
interface Moderator extends User {
type: 'mod'
}
function test(u: User) {
return u;
}
const admin: Admin = {
type: 'admin',
name: 'Tom'
}
test(admin) // admin can be used as user
}
{
// algebraic types version - familiar for functional programmers Haskell, Elm
type User = {
type: string
name: string
}
type Admin = User & {
type: 'admin'
}
type Moderator = User & {
type: 'mod'
}
function test(u: User) {
return u;
}
const admin: Admin = {
type: 'admin',
name: 'Tom'
}
test(admin) // admin can be used as user
}
在 TS 中,你不需要使用任何接口type
,只需使用交集和并集等类型运算符即可完成所有操作。没错!
注意:你是否知道,面向对象编程的最初概念与继承无关。Alan Kay 提出这个术语时,主要关注的是封装和消息传递。
TypeScript 中的函数式编程很难
最后一个超出了原始论点,但如果不是 OOP,那么自然的选择就是函数式编程,所以如果我们放弃类,我们很可能会以函数式风格编写函数和数据转换。
那么,在 TS 中进行函数式编程比在 JS 中更难吗?是的,稍微难一点,但幸运的是,有一些工具可以解决这个问题,大多数著名的 JS 函数库都是全类型化的,所以如果你使用Ramda,它就有对应的类型。此外,还有一些专门为 TS 编写的库,例如fp-ts,它们代表了纯静态函数式语言的类型构造和实用程序。所以,是的,我们可以完全实现函数式编程!
注意:借助 TS 4.0 的最新功能 - 可变元组类型,FP 建模稍微简单一些!
那么误解从何而来?
可能来源很少
- TS 的创造者与 C# 的创造者是同一个人
- TS 在 JS 之前就有类和私有字段
- 类型符号(接口、泛型)类似于 Java、C#
第一个说法相当错误,因为创造了一种语言的人没必要让其他语言也变得一样。第二个说法只在历史上是正确的,但现在已经是2020年了,不是吗?第三个说法只与语法有关,虽然看起来很相似,但与语言是否面向对象无关。
需要明确的是,TypeScript 是面向对象的语言,但面向对象并不比 JavaScript 本身更好。历史上确实如此,因为 TypeScript 引入了类、私有字段和继承,而 JS 中并没有这些功能。但现在情况并非如此,所有与面向对象相关的功能都存在于 JS 中,TypeScript 只是在其基础上添加了类型级别。
TypeScript 是 JavaScript 的附加静态类型层,两者都是多范式编程语言。下次如果有人告诉你 TypeScript 只适用于面向对象编程,请告诉他这不过是一派胡言。
文章来源:https://dev.to/macsikora/no-typescript-is-not-oop-version-of-javascript-3ed4