使用 TypeScript“严格”模式进行类型严格编码

2023-11-29 21:18:57 浏览数 (1)

工作经历回顾

大约两周前,我决定解决一个与我之前做过的很多工作不相关的问题。一些背景信息,我在 C 和 C 方面有丰富的经验,这些语言通常是类型严格的。但是,当考虑到我花费大量时间开发网站等项目时,我从未真正使用过 TypeScript 或其严格模式。我习惯了 JavaScript 的无类型自由和一些繁琐的事情,于是我决定尝试完全相反的东西。在 TypeScript 中工作是一次有趣的经历,严格模式让我想起了在 VS 中使用 C/C 的感觉。无论如何,这是我在解决这个问题时经历的过程。

工作流程

幸运的是,这个问题本身给了我一个直接链接到严格模式文档的链接。我浏览了一下,过了一遍启用和维护严格模式代码库的一些检查和要求,然后很快就开始工作了。

我浏览了包含 Blockly 插件的文件夹,并直接进入了其 tsconfig.json 文件以启用严格模式,非常简单。这样做之后,我运行了 npm run build,显示了许多由于严格模式类型检查而需要修复的错误。

这些错误中的许多是相当简单的,例如 TS2531: Object is possibly 'null'。这只是对 null 做了一个检查,以确保在不期望的情况下不使用 null 值。其他的错误,例如 TS2564: Property 'minimapWrapper' has no initializer and is not definitely assigned in the constructor. 简单地意味着在类中声明了某些内容,但是不可为空,因此必须在构造函数中赋值。看到我在几乎是 JavaScript 的代码中遇到了在 C 中经常遇到的异常和错误,这有点滑稽,但这也意味着我对如何修复它们有了一个相当好的想法。

例如,许多情况可以通过以下方式解决:

代码语言:typescript复制
// old
protected minimapWrapper: HTMLDivElement;
// new 
protected minimapWrapper: HTMLDivElement | null = null;

这个简单的更改意味着变量现在可以默认为 null,因此在构造函数中不需要分配任何内容。然而,这也带来了一系列额外的问题。既然我们知道 minimapWrapper 可以预期为 null,那么当我们实际上期望有一个值时会发生什么呢?这就是空检查起作用的地方。幸运的是,有许多不同的方法来处理这个问题。每当代码需要 minimapWrapper 有一个值时,严格模式就会对我们大声呼喊,除非我们包含这个简单的检查:

代码语言:txt复制
if(!minimapWrapper) {
  // Do something...
}

这实质上是我需要做的大部分变更,但在测试文件中出现了一个奇怪的问题。

由于某种奇怪的原因,DOM 的引用没有被链接,这意味着由于需要 DOM 引用来获取对象的位置,插件的特定功能无法进行测试。经过一番挖掘,我发现将以下内容添加到文件顶部可以解决问题:

代码语言:txt复制
const jsdom = require('jsdom');
const { JSDOM } = jsdom;

const { document } = (new JSDOM('')).window;
global.document = document;

这很可能是因为我们通过一个空的 HTML 文档来强制引用 DOM。

更改请求和实际修改

提交我的初始 PR 后,解释了所做的更改以及我面临的 npm run test 问题,要求进行了各种更改。其中很多都是非常简单的更改,无论是使某些内容不可为空并在构造函数中分配它们,还是修复某个函数的格式。这个 PR 还没有被合并,但这很可能是由于测试运行的问题,审阅者表示他们会对此进行详细调查。

自 Hacktoberfest 以来的进展

这是我第一次对一个现有的、复杂的代码库进行了相当大的更改。它带来了许多惊喜,我惊讶地发现从一开始就很容易理解所有内容。

总结感想

使用 TypeScript 实际上是一次很有趣的经历,我喜欢对比它和 C 。看到一些我从未预料到会在 JavaScript 中看到的错误,真是令人惊叹,让我感觉就像是在使用一种非常熟悉但又不同的语言进行编程。我期待着尝试一些更多的 TypeScript 项目。感谢阅读,下次再见!

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞