发布于 2026-01-06 5 阅读
0

致 TypeScript 的一封情书

致 TypeScript 的一封情书

亲爱的 TypeScript,我知道你的兄弟 JavaScript 有时可能不希望我们在一起,但我认为你的优点值得我们这样做,这就是我爱你的原因!

玩笑归玩笑,自从我开始认真研究 TypeScript 的众多特性及其魅力以来,我就一直很想写这篇文章。封面图片中的代码并非只是摆设,像这样简单的示例就能展现我爱上 TypeScript 的诸多原因,以及我今后想要尽可能多地使用它的愿望。因此,废话不多说,让我们开始慢慢写这封情书吧。

提到 JavaScript,我们总是会想到它的灵活性。它赋予了代码编写极大的​​灵活性,JavaScript 非常宽容,你可以在对象中添加字段、删除字段,函数可以作为参数传递,数组可以容纳任何“类型”的元素(JavaScript 对类型的定义非常宽松)。然而,所有这些灵活性都是有代价的。当我看到一个用 JavaScript 编写的、超过 100 行代码且只有一个文件的应用程序时,我总是觉得它很混乱,我这么说并无冒犯之意。我不知道代码的来源和去向。这就像踏入雷区。我的背景是 Java,在 Java 中,你可以控制几乎所有你编写的代码,有时这种控制甚至过强。

这就是 TypeScript 的用武之地,它融合了 JavaScript 的灵活性,同时又兼具静态类型语言的控制力。对我来说,它完美地结合了 JavaScript 和 Java 的优点(千万别把它们混淆)。那么,让我们来看一个例子。首先,我们来看Letter接口。

export interface Letter {
  from: string;
  to: string;
  message: string;
}

好的,很正常,对吧?我喜欢 TypeScript 接口的一点是,你可以同时定义属性和方法,而实现它们的类必须具备所有这些属性才能满足接口的要求。这与 Java 不同,Java 中的“属性”是接口内部的常量,它们并非真正的属性。然而,TypeScript 中的接口与其他类一样,展现出了强大的功能。所以,我们在下面展示这个LoveLetter类。

export class LoveLetter {
  constructor(public from: string, public to: string) {}

  get message(): string {
    return `I love you, ${this.to}`;
  }
}

如果你不了解 TypeScript 的强大之处,光看这个类可能不会意识到,但它完全符合Letter接口要求,100% 满足!首先来看构造函数。在 Java 中,总是需要添加参数并立即将其赋值给类属性,这很烦人,也是不必要的样板代码!我喜欢 TypeScript 的做法,只需在构造函数的参数中插入 `__init__` publicprivate`__init__` 等,就可以一次性声明类属性并为其赋值。因此,LoveLetter该类具有字符串属性to,并且from需要Letter……

“但是如果是 `getter` 方法呢messageLoveLetter它明明是一个方法,而不是字符串属性!”你可能会这样问。这正是 TypeScript 的另一个非常有趣的特性:“getter 方法”。它的用法很像 Java 中的 getter,但 TypeScript 有一个 Java 没有的陷阱。当你在get函数名前加上 `getter` 时,TypeScript 会把它当作属性来处理!所以,我们可以这样写:`getter`,letter.message而不是这样写:`getter` letter.message()。由于 TypeScript 将其视为属性,因此可以满足Letter接口的要求。当你想以另一种方式处理数据时,例如为了视觉效果,它非常有用,就像我处理“我爱你,#name#”时那样,使用字符串插值插入收件人的姓名。在简单的例子中,这可能看起来差别不大,但当你需要满足一些大型接口或处理更复杂的用例时,它就派上用场了。

对于一些习惯于 Java 的人来说,TypeScriptclass Foo implements Bar中类无需像 Java 那样进行正式声明就能实现接口,这听起来可能很奇怪。但这正是 TypeScript 接口如此强大的原因之一:类仅凭其结构就能满足接口要求,无需正式声明。当然,你也可以进行正式声明:

export class LoveLetter implements Letter {
  constructor(public from: string, public to: string) {}

  get message(): string {
    return `I love you, ${this.to}`;
  }
}

这种声明方式与 Java 完全相同,这样,如果类不满足接口,就会在类级别显示错误信息,但通常情况下,你不需要如此明确地声明。因此,如果一个类仅通过形状满足接口,那么你可以直接跳到示例的最后一部分:

const sendLetter = (letter: Letter) => {
  console.log(
    `From: ${letter.from}
    To: ${letter.to}

    ${letter.message}
    `
  );
};

const loveLetter = new LoveLetter('Developer', 'TypeScript');
sendLetter(loveLetter);

这里我们有一个被赋值给常量并声明为箭头函数的函数。在这个例子中,它本身并没有什么特殊含义,但箭头函数可以使代码更加优雅,尤其是在 TypeScript/JavaScript 中频繁使用回调函数的情况下。此外,它还可以解决一些作用域方面的问题,尤其是在处理 `__init__` 类型时this,不过我们以后再详细讨论。接下来,我们创建了一个新的 `__init__` 对象LoveLetter并将其赋值给一个常量,这没什么特别的,但下一行代码展示了接口的一些强大之处。虽然该函数接收一个 ` Letter__init__` 类型的参数,但由于LoveLetter`__init__` 完全符合接口的要求,因此你也可以使用 `__init__` 类型的实例来调用该函数LoveLetter!更棒的是,你不需要在任何地方告诉 TypeScript 这一点,它会自动识别。同样,接口是通过其形状来评估的,如果形状正确,就可以正常使用了!

每天学习 TypeScript 都让我感到非常兴奋,它巧妙地将我已掌握的语言中我最喜欢的部分融合到了一种优美的语言之中。TypeScript 还有许多其他值得一提的特性,但我相信通过这个简单的例子,你就能感受到它的强大之处。我相信 TypeScript 在市场上拥有光明的前景,我向所有人推荐它。别担心,我不会因为 TypeScript 的流行而嫉妒它。

文章来源:https://dev.to/leoat12/a-love-letter-to-typescript-56o0