程序员技术开发

小心TypeScript编写出无用的代码

2020-10-31  本文已影响0人  岛上码农

本文翻译自The Daily WTF网站,原作者的大意是TypeScript相比JavaScript确实有很多优势,但是这个优势其实是编译器带来的。在编写TS代码的时候应当重视编译器的警告,因为有些代码转换成JS后可能并不会有错误,但是实际上因为JS缺少TS的一些特性,可能会导致代码运行出问题。

TypeScript相比JavaScript有一定的优势。编译时检查能够发现很多代码编写的错误,相比浏览器而言发展更快,与最新的行业标准更匹配(编译器将那些与浏览器解释转化讨厌的细节全部搞定了),而且TS还有更方便好用的语法糖。
如果你在使用TS,你可以使用编译器发现代码中很多丑陋的问题,而你要做的就是把那些标红的错误修改掉。或者,你可以像昆塔斯(Quintus)的同事那样,就像,呃,下面的代码。

/**
 * Container holding definition information.
 *
 * @param String version
 * @param String date

 */
export class Definition {
  private id: string;
  private name: string;
  constructor(private version, private data) {}

  /**
   * get the definition version
   *
   * @return String version
   */
  getVersion() {
    return this.id;
  }

  /**
   * get the definition date
   *
   * @return String date
   */
  getDate() {
    return this.name;
  }
}

现在,如果你想在TS的环境中运行这段代码,你会发现在编译和转换成JS过程中,编译器合理地指出了一堆警示。然而,如果你用命令行工具tsc编译,默认设置下却没有任何警示。

因此,如果TypeScript代码写得不好,编译器工具可以告诉你代码的问题所在,但是前提是你得要求编译器工具按你的要求检查。

不管怎么说,很容易理解这个糟糕的代码会发生什么:这显然是通过复制/粘贴完成的编码。代码定义了一个拥有id和name属性的类。复制/粘贴的时候却弄成了version和date,然后可能是代码还没改完,中途被什么事打断了。他们也像模像样地检查了代码,但是却没人发现——直到昆塔斯站在旁边的时候。

再来聊聊这段代码,你会发现id和name是私有属性,构造器又定义了另外两个属性(通过构造器进行关联):私有的version和data参数。因此,当调用构造函数的时候,实际上初始化了根本没有对应访问方法的两个私有成员。确实是有成员访问方法,但是实际使用却是id和name的,而id和name既没有在构造方法初始化,也没有外部设置的入口。

由于TS编译成了JS,而JS是没有private这个关键字的,因此编译成JS并不会有任何警告。我猜想这段代码最终胎死腹中,并没有真正派上用场。如果需要用的话,我敢打赌是下面这样的。

let f = new Definition();
f.id = "1.0.1"
f.name = "28-OCT-2020"
…
let ver = f.getVersion();

这段代码可以按照原先的开发者预期那样正常运行,但是如果他们这么做的话,TS编译器就会报警——然而,如你所见,他们并不真的关心编译器的那些警告。

上一篇下一篇

猜你喜欢

热点阅读