【问题标题】:TypeScript conditional Exclude type exclude from interfaceTypeScript 条件排除类型从接口中排除
【发布时间】:2019-08-07 11:08:44
【问题描述】:

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

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??

【问题讨论】:

    标签: typescript typescript-typings


    【解决方案1】:

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

    一种方法如下:

    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&lt;T, V&gt;,我们可以注意到{ [K in keyof T]-?: T[K] extends V ? never : K }[keyof T] 类型将返回T 中的键,其属性不能分配给V

    如果TTest 并且VFunction,这将变成类似

    { 
      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"
    

    一旦我们有了这些键,我们就从T Pick 获取它们的属性(使用Pick&lt;T, K&gt; utility type):

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

    变成想要的类型

    {
      a: string,
      b: number
    }
    

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

    Link to code

    【讨论】:

    • 像魅力一样工作,非常聪明!
    猜你喜欢
    • 1970-01-01
    • 2022-08-18
    • 2017-12-12
    • 2021-09-09
    • 2016-12-10
    • 2018-06-21
    相关资源
    最近更新 更多