小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
背景
大家好,我是梅利奥猪猪!上次赖掉的omit这次肯定是逃不过了,请大家omit(omit直译就是忽略)下开头讲的这几句废话。其实上次讲解的Exclude就是为了这次做铺垫的,大家谅解下,听我娓娓道来!
正文
官方例子
先来看下官方的例子,以及说明
Constructs a type by picking all properties from Type and then removing Keys (string literal or union of string literals).
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
createdAt: 1615544252770,
};
todo;
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
const todoInfo: TodoInfo = {
title: "Pick up kids",
description: "Kindergarten closes at 5pm",
};
todoInfo;
咳咳又是官方套路,老Todo选手了!todo选手拥有4个字段
- 过了n天,我说不改原本的接口,把description字段去了,新接口只要剩下的字段
- 又过了n天,我说不改原本的接口,我又要开始闹腾了,description我还是要的啊,completed和createdAt这2个我不要了,其他都要 Omit这个时候就登场解决了所有问题,我可以生成新的接口,你哪些字段不要告诉我就可以了,牛逼!知道Omit是干嘛用的,接下来我们实现下
分步实现
实现的原理,就是转换个角度思考,Omit不是剔除字段,保留剩下的字段嘛,那我们pick除了它不要的字段,其他字段都要不就可以了,先来搭架子
type MyOmit<T, K>
为什么是有T和K两个泛型(别打了别打了,竟然不给我说废话),这里注意下,K肯定是个string或者number或者symbol,所以我们可以进化下架子
type MyOmit<T, K extends keyof any>
然后我们的逻辑不是要改写成Pick嘛,所以肯定是要Pick原本接口的字段,再进化下
type MyOmit<T, K extends keyof any> = Pick<T, keyof T>
细心的小伙伴可能会发现,我们之前申明的K,即需要排除的字段都没有用到,所以上次我们说的Exclude就要登场了,我们Pick的字段,就是排除了K以外的字段,究极进化开始
type MyOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>
继续废话文学,中文直译,先看Exclude<keyof T, K>
原本T里的字段,我写了需要排除的K字段,那剩下的就是我要的,接下去再使用Pick,不就是把我需要的字段,组装成我想要的新接口!完结撒花
源码讲解
直接上源码
/**
* Construct a type with the properties of T except for those in type K.
*/
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
和我们写的一毛一样,XDM我们大家都是小天才哈哈,具体实现步骤大家有不清楚可以再对照分步实现看,这里就不赘述了,那么我们的Omit实现之旅到此结束了!