likes
comments
collection

TypeScript ——如何更好地组织、存储和声明类型文件

作者站长头像
站长
· 阅读数 16

一、背景

  • 背景:随着TypeScript项目越来越庞大,项目中会有很多类型声明,有时A开发一个模块时,声明了 TypeA,B声明 TypeB,这两个类型非常相似,但由于A不知道B也声明了类似的类型,导致两人重声明,可能每个人存放类型文件的位置也不一样,日积月累,项目中的类型文件越来越混乱。
  • 整体思路:参考现有方法,并针对项目已有情况进行类型文件整理,规范项目结构。

二、实现步骤

2.1 常见方式

方式1 全局 types.ts 文件

  • 优点:方便存储,只需要维护一个文件,类型可以进行复用,方便查看相似类型,避免多次编写。
  • 缺点:如果项目很大,文件会上千行,也会导致命名困难,非常不利于维护、合并冲突将是经常遇到的问题。
|--src
  |-- types.d.ts    // 全局的类型文件
  • 优化方法1:可以根据一定维度(页面、组件、接口等)划分 namespace

声明时:

TypeScript ——如何更好地组织、存储和声明类型文件

使用时:

直接namespace.Type 即可使用,无需导入。

TypeScript ——如何更好地组织、存储和声明类型文件

  • 优化方法2:可以通过 /** */ 形式的注释为给 TypeScript 类型做标记提示:

声明时:

TypeScript ——如何更好地组织、存储和声明类型文件

使用时:

TypeScript ——如何更好地组织、存储和声明类型文件

\

方式2 按模块(页面、组件、接口等)划分

  • 优点:按模块划分,
  • 缺点:容易多次编写重复类型。
|--src
  |-- types
    |-- common        // 公共类型
        |-- common9.ts
    |-- components    // 组件的类型
        |-- button.ts
    |-- api           // 页面中的请求类型
        |-- api1.ts
    |-- pages         // 页面中的props等类型
        |-- page2.ts    
    |-- store         // 全局 状态类型
        |-- store4.ts
...

2.2 调研业内组织和存储类型文件的方法

  • TypeScript 团队 使用一个**types.ts** ****统一管理所有类型: 链接
  • Vite团队 使用 **types**文件夹 按模块来管理类型: 链接
  • Tencent 团队 使用 从组件/页面等模块导出 类型来管理类型 链接
  • ...

2.3 项目现状

存在问题:

  • 存在大量重复声明

TypeScript ——如何更好地组织、存储和声明类型文件

  • 命名不规范、无法区分模块

TypeScript ——如何更好地组织、存储和声明类型文件

  • any数量过多

TypeScript ——如何更好地组织、存储和声明类型文件

三、解决方案

  • 减少any数量

TypeScript ——如何更好地组织、存储和声明类型文件

以一个出现17次any的单文件为例

发现有很多any是因为事件的event的类型不知道怎么定义

  1. 逐步排查、解决方法:
  • 第一时间联想到 Event类型

TypeScript ——如何更好地组织、存储和声明类型文件

发现并不能解决问题

原因是因为React针对不同事件都封装了专门的类型

TypeScript ——如何更好地组织、存储和声明类型文件

  • 定位到使用位置、根据提示确定类型

TypeScript ——如何更好地组织、存储和声明类型文件

可以看出 onMouseDown的类型 为React.MouseEventHandler<HTMLDivElement> | undefined

再回到声明方法的位置,添加类型

TypeScript ——如何更好地组织、存储和声明类型文件

可以看到已经为e添加了类型,可以享受ts带来的语法提示。

  1. 根据上下文判断类型

TypeScript ——如何更好地组织、存储和声明类型文件

cellsList已有类型,看代码可知rowGroup是依赖cellsList的一部分属性

rowGroup 是二维数组,cellsList是一维数组,需要在item类型上进行 拓展 如图

TypeScript ——如何更好地组织、存储和声明类型文件

还有可能会写这样的类型,虽然第一时间不会有错误,但是如果 cellsList 类型有改动,则rowGroupItemType依赖的 itemsList 的类型 会不匹配

TypeScript ——如何更好地组织、存储和声明类型文件

四、eslint约束

可以使用eslint限制项目中ts的规范 如 '@typescript-eslint/no-explicit-any': 'error'不允许显式的 any 类型。

TypeScript ——如何更好地组织、存储和声明类型文件 更多 lint规则

五、总结

不同的模式和框架从事不同的项目、都会养成不同的编码习惯,需要针对项目进行灵活的规划。

只有在编写越来越多的代码并且项目规模逐渐增长以及团队成员逐渐变多之前,才会看到最适合每种

类型的项目甚至项目的每个阶段的组织结构。

参考文章

TypeScript | Organizing and Storing Types and Interface

How to organize TypeScript interfaces