主题
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 类型所有字段都变成可选的&
作用是联合类型,两个类型取交并集