首页 > 解决方案 > TypeScript 条件排除类型从接口中排除

问题描述

根据文档,我可以使用预定义的排除类型从某种类型中排除某些属性:

type Test = string | number | (() => void);

type T02 = Exclude<Test, Function>;

但是,如果我有 Test 接口而不是 Test 类型,它似乎不起作用。在以下情况下如何获得类似的结果?

interface Test {
  a: string;
  b: number;
  c: () => void;
} 

// get somehow interface with excluded function properties??

标签: typescripttypescript-typings

解决方案


要获得这种效果,您需要找出匹配的属性Function,然后有选择地排除它们。等效地,我们找到哪些属性不匹配Function,然后选择性地包含它们。这比仅仅排除工会的某些部分涉及更多;它涉及映射类型条件类型

一种方法如下:

type ExcludeMatchingProperties<T, V> = Pick<
  T,
  { [K in keyof T]-?: T[K] extends V ? never : K }[keyof T]
>;

type T02 = ExcludeMatchingProperties<Test, Function>;
// type T02 = {
// a: string;
// b: number;
// }

检查ExcludeMatchingProperties<T, V>,我们可以注意到该类型{ [K in keyof T]-?: T[K] extends V ? never : K }[keyof T]将返回T其属性不可分配的键V

如果TisTestVis Function,这就变成了

{ 
  a: string extends Function ? never : "a"; 
  b: number extends Function ? never : "b"; 
  c: ()=>void extends Function ? never : "c" 
}["a"|"b"|"c"]

,变成

{ a: "a"; b: "b"; c: never }["a"|"b"|"c"]

,变成

{ a: "a"; b: "b"; c: never }["a"] | 
{ a: "a"; b: "b"; c: never }["b"] | 
{ a: "a"; b: "b"; c: never }["c"]

, 或者

"a" | "b" | never

, 或者

"a" | "b"

一旦我们有了这些键,我们就Pick从它们的属性中获取它们T(使用Pick<T, K> 实用程序类型):

Pick<Test, "a" | "b">

成为所需的类型

{
  a: string,
  b: number
}

好的,希望有帮助;祝你好运!

链接到代码


推荐阅读