在TypeScript中使用Exclude的9种方法

图片

作为一名TypeScript开发者,我经常被问到很多关于TypeScript工具类型的问题——尤其是如何在应用程序代码中使用它们。所以,我开始了一个关于它们的系列——围绕现实世界的例子。

让我们从 Exclude 类型帮助器开始。

1. 移除联合的成员

 

type Fruit = "apple" | "banana" | "orange"; type Result = Exclude<Fruit, "orange">;      // type Result = "apple" | "banana"

可以使用 Exclude 删除联合的单个成员。第一个参数表示完整的联合,第二个参数表示要删除的成员。

从技术上讲,第二个参数可以是任何类型——如果你试图删除一个不存在的成员,TypeScript不会警告你。它只会返回原来的组合。

 
type Result = Exclude<Fruit, "pear">;      // type Result = "apple" | "banana" | "orange"


2. 从联合中删除多个成员
 

type Event = "click" | "focus" | "change" | "abort";
type ClickAndFocusEvent = Exclude<  Event,  "change" | "abort">;

还可以使用 Exclude 从联合中删除多个成员。通过将联合传递给第二个实参,可以一次删除多个成员。

如上所述,并非所有这些成员都需要存在于原始联合中:

 
type ClickAndFocusEvent = Exclude<            // type ClickAndFocusEvent = "click" | "focus"  Event,  "change" | "abort" | "blur">;

3. 移除区分联合的成员

 

type Event =  | {      type: "click";    }  | {      type: "focus";    }  | {      type: "change";    };

区分联合通常是对象之间的联合,这些对象具有可用于区分它们的共同属性。在上面的示例中, type 属性用于区分不同的事件。

通过使用 Exclude 删除所有没有 type 属性特定值的成员,可以提取联合的一个子集。

 
type Event =  | {      type: "click";    }  | {      type: "focus";    }  | {      type: "change";    }; type ClickAndFocusEvent = Exclude<               // type ClickAndFocusEvent = {               //   type: "click";               // } | {               //   type: "focus";               // }  Event,  { type: "change" }>;

即使联合的成员具有附加的其他属性,这也可以工作。

type Event =  | {      type: "click";      x: number;      y: number;    }  | {      type: "focus";    }  | {      type: "change";      value: string;    }; type ClickAndFocusEvent = Exclude<Event, { type: "click" }>; // { type: 'focus' } | { type: 'change', value: string }

在上面的例子中,为了移除 click 事件,不需要将 x 和 y 属性传递给 Exclude 。


4.移除区分联合的多个成员

 

type Event =  | {      type: "click";    }  | {      type: "focus";    }  | {      type: "change";    }  | {      type: "abort";    }; type ClickAndFocusEvent = Exclude<              // type ClickAndFocusEvent = {              //    type: "click";              // } | {              //    type: "focus";              // }  Event,  { type: "change" } | { type: "abort" }>;

还可以通过将联合传递给第二个参数来删除有区分联合的多个成员。它可以是联合成员的并集,也可以是 type 属性的并集:

type ClickAndFocusEvent = Exclude<  Event,  { type: "change" | "abort" }>;
 


5. 通过形状排除区分联合的成员
 

 
type Routes =  | {      route: "/user";      search: {        id: string;      };    }  | {      route: "/user/create";    }  | {      route: "/user/edit";      search: {        id: string;      };    }; type RoutesWithoutSearch = Exclude<            // type RoutesWithoutSearch = {            //     route: "/user/create";            // }  Routes,  {    search: any;  }>;

您不需要在 Exclude 的第二个参数中包含'discriminator'(在本例中为 route )。你可以只传递你想要移除的成员的形状。

在上面的例子中,我们删除了 Routes 联合中所有具有 search 属性的成员。


6. 从联合中删除所有字符串/数字/布尔值

 

type PossibleTypes = "admin" | "user" | 0 | 1 | 2; type StringTypes = Exclude<PossibleTypes, number>;         // type StringTypes = "admin" | "user"

Exclude也适用于基本类型。在上面的例子中,我们从 PossibleTypes 联合中删除了所有匹配 number 的字面值。

如果您想要从联合中删除所有字符串、所有数字或所有布尔值,这将非常有用。


7. 从联合中删除包含子字符串的字符串

 

type ObjectKey =  | "userId"  | "postId"  | "userName"  | "postName"; type PostKey = Exclude<       // type PostKey = "postId" | "postName"  ObjectKey,  `${string}${"user"}${string}`>;

可以使用 Exclude 从联合中删除包含特定子字符串的所有字符串。

在上面的例子中,我们从 ObjectKey 联合中删除了所有包含子字符串 user 的字符串。

我们使用模板字面值来表示要删除的字符串——在本例中为 user 。然后使用 ${string} 语法来表示出现在要删除的子字符串之前或之后的任何字符串。


8. 从联合中删除具有几个可能值之一的字符串

 

type ObjectKey =  | "userId"  | "postId"  | "id"  | "userName"  | "postName"; type NonIdKey = Exclude<        // type NonIdKey = "userName" | "postName"  ObjectKey,  `${string}${"id" | "Id"}${string}`>;

还可以使用 Exclude 从联合中删除包含几个可能的子字符串之一的所有字符串。

在上面的例子中,我们从 ObjectKey 联合中删除了所有包含 id 或 Id 的字符串。通过向模板文本传递一个联合,我们可以一次删除多个子字符串。


9. 从联合中删除具有特定前缀/后缀的字符串

 

type ObjectKey =  | "userId"  | "postId"  | "id"  | "userName"  | "postName"; type NonNameKey = Exclude<ObjectKey, `${string}Name`>;         // type NonNameKey = "userId" | "postId" | "id"

您可以使用 Exclude 从联合中删除具有特定前缀或后缀的所有字符串。

在上面的例子中,我们从 ObjectKey 联合中删除了所有以 Name 结尾的字符串。

这里, ${string} 用于表示在要删除的子字符串之前出现的任意长度的字符串。

要将其转换为匹配某个前缀,可以将 ${string} 移到模板字面值的末尾。


我错过了什么?
 

Exclude 是一个非常强大的实用程序类型,可以以多种方式使用。如果你有其他使用 Exclude 的例子,请在文章下方留言告诉我!

 欢迎关注公众号:文本魔术,了解更多

  • 28
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值