编写 .d.ts 时的一些心智技巧

avatar
前端开发工程师 @阿里巴巴

作者:ICBU 东墨

写在最前:欢迎来到阿里巴巴 ICBU 交互&端技术前端团队专栏,我们将与你分享优质的前端技术文章,欢迎关注&交流哟!

前言

TypeScript 的类型标注、提示功能是一个投入大、但收益也大的特性。经常听到这样的声音:

"编辑器提示一时爽,类型编辑火葬场".

谁都想做吃水者,也总要有人来吃挖井人的苦。如果你刚好是一个挖井人,这里有一些关于 TypeScript 的心智技巧也许可以帮到你。

1. 准备属于你自己的一些基础 ts-generic-helper 库

TypeScript 从 2.8 开始已经内置了一些基础的泛型 helper, 比如 Parameter, Reverse, Pick 等,有时候一些内置的类型库。

这里是我的一型类型库,里面收录了之前常用的一些 Generic Type Helper

2. 尽量直接从 ts 生成 *.d.ts

一些流行的 npm 包基于 js 开发, 今年来才开始支持 *.d.ts 用于类型提示, 这样的 npm 包的代码仓库往往是 js 和 *.d.ts 分开维护的.

如果你有一个新开的仓库, 并且希望你为你的使用者提供类型提示, 尽量使用 TypeScript 自己的 type emitation 来生成 *.d.ts. 因为如果你使用 js 编写并单独维护一份 *.d.ts, 两个坏处:

  • 你必须手动同步 js/*.d.ts 的各种导出成员的类型和函数签名
  • 在上述过程中你非常容易犯错.

在 tsconfig.json 中打开对应的选项,TypeScript 自带的 tsc 会为你自动生成对应的 *.d.ts 文件:

{
      "declaration": true,
      "declarationDir": "..." // 可选, 可以指定类型文件的生成目标目录
}

Copy

3. 尽量不要在函数回调中使用 any

一般人能尽量遵循 "不要使用 any" 的原则, 标注清楚每个变量的类型. 但很多人会在函数签名上偷懒.

假设有一个回调函数 cb, 其被调用时第一个参数是一个具体的结构体 {foo1: string, foo2: string}, 不要偷懒

// 不要这样
function cb(payload: any);

// 写成这样
function cb({foo1: string, foo2: string});

Copy

4. 标注你的 Promise resolve 类型

Promise 也是类似的道理, 如果你自定义了一个 Promise (而不是用 async 函数并且在函数体内返回可推断类型的值), 请标注它 resolve 类型.

// 不要这样
return new Promise ((resolve, reject) => {
    someAsyncLogic((success) => {
        if (success) {
            resolve({...})
        } else {
            reject('...');
        }
    })
})

Copy

不标注 resolve 类型的 Promise, 之后当你使用它的时候, 在 .then((val) => {}) 中你将无法知道 val 的类型是什么.'

// 标注了 resolve 类型
return new Promise<{ foo: string, bar: number }> ((resolve, reject) => {
    someAsyncLogic((success) => {
        if (success) {
            // 如果这里提供的值和上面标注的不符, 编辑器和编译器都会报错
            resolve({...})
        } else {
            reject('...');
        }
    })
})

Copy

5. 复用你使用过的类型

你可以从已经编写好的复杂 interface 中提取你需要的字段, 参考这里

随着 TypeScript 的类型推断功能日益强大,现在你几乎可以从任何现有类型中推断出其它类型。

结语

写 TypeScript 类型可能是一件繁琐的事情, 甚至被冠以"类型体操"的调侃. 但对于复杂的应用开发, 对它的前期投入将会在后期带来良好的维护收益.

❤️ 感谢你看到最后~

阿里巴巴国际站(ICBU,Alibaba.com)是全球最大的跨境贸易和服务平台。我们时刻有新的技术挑战,有足够有趣的挑战满足你所有的好奇心和求知欲,有国外知名合作团队(Google & OpenSky)。

如果你想来 ICBU 和我一起开发前端,欢迎发简历到邮箱 shudai.lyy@alibaba-inc.com ,我们将快速响应你的面试安排。:-)