主题
Ts 实现 Optional 来避免类型重复定义
需求场景以及存在的问题
现有一个文章的类型 和一个创建文章的方法
typescript
interface Article {
title: string;
content: string;
author: string;
date: Date;
readCount: number;
}
function createArticle(article: Article) {}在创建文章的时候,传的参数与Article有区别,有些参数是可选的,有些参数又是必须的
此时,常规的做法是新创建一个CreateArticle类型,例如:
typescript
interface CreateArticle {
title: string;
content: string;
author: string;
date?: Date;
readCount?: number;
}但是你会发现,CreateArticle与Article两个类型的字段都长一样,只是CreateArticle有部分字段是可选的,有如下一些问题:
Article与CreateArticle类型字段有很多重复的部分,需要些很多重复代码- 当
Article新增字段或者修改字段名,CreateArticle也需要同步更改,维护困难
因此,我们希望有一中方式,来根据Article算出CreateArticle,这就是下面要说的 Optional
Optional 类型工具的实现
假设 Optional 的使用方式为:
typescript
type CreateArticle = Optional<Article, "date" | "readCount">;得到的 CreateArticle 类型就是 date 和 readCount 是可选的参数,其余为必选的参数,具体实现如下:
typescript
type Optional<T, k extends keyof T> = Omit<T, k> & Partial<Pick<T, k>>;效果展示

实现细节解释
Optional<T, k extends keyof T>泛型,T为原始的类型,后面k extends keyof T表示 K 来自于 T 中的字段,也是一个约束,不至于让传进来的字段是乱写的Omit<T, k>,Omit 是 TS 引擎自带工具,作用是将 T 里面的 K 字段统统扔掉Pick<T, k>,Pick 也是 TS 引擎自带工具,作用刚好和 Omit 相反,是将 T 里面所有 K 字段挑选出来Partial<O>,Partial 是 TS 引擎自带工具,的作用是将 O 类型所有字段都变成可选的&作用是联合类型,两个类型取交并集
