【问题标题】:How to Omit property in type by property type如何按属性类型省略类型中的属性
【发布时间】:2019-07-16 01:37:40
【问题描述】:

我有一些属性类型为字符串、数字等的类型,我想省略一些类型不是字符串的属性。

Omit<T, U> 泛型只是省略了属性名称,而不是属性类型。

例如:

class Person {
  name: string;
  age: number;
  eat(food: Food): void;
  walk(miles: number): void;
  read(book: Book): void;
}

// =>

type PersonAbility = PickAbility<Person>;

// how can i write a PickAbility<T> generic, results:

type PersonAbility = {
  eat(food: Food): void;
  walk(miles: number): void;
  read(book: Book): void;
}

如上面的代码。

我已经尝试过了:

type PersonAbility = {
  [K in keyof Person]: Person[K] extends (payload: {}) => Promise<{}> ? Person[K] : never
};

// it results:

type PersonAbility = {
  name: never;
  age: never;
  eat: (food: Food) => void;
  walk: (miles: number) => void;
  read: (book: Book) => void;
}

上面的代码将不需要的属性设置为never,但不删除它。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这里的解决方案是获取与你想要的属性值对应的键的并集,然后Pick那些。这是一种方法:

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

    KeysMatching&lt;T, V&gt; 使用mapped、conditional 和lookup 类型来查找类型为T 的键,其属性值可分配给类型V。

    然后我们可以将 PickMatching&lt;T, V&gt; 设为 Picks 这些值:

    type PickMatching<T, V> = Pick<T, KeysMatching<T, V>>;
    

    而PickAbility&lt;T&gt; 只会在Function-valued 属性上使用PickMatching(您的示例代码使用(payload: {}) =&gt; Promise&lt;{}&gt;,但您的Person 方法都不匹配):

    type PickAbility<T> = PickMatching<T, Function>;
    

    让我们测试一下:

    type PersonAbility = PickAbility<Person>;
    /*
    type PersonAbility = {
        eat: (food: Food) => void;
        walk: (miles: number) => void;
        read: (book: Book) => void;
    }
    */
    

    看起来不错。希望有所帮助;祝你好运!

    Link to code

    【讨论】:

      猜你喜欢
      • 2019-09-06
      • 2021-09-16
      • 2021-07-06
      • 2015-09-01
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      相关资源
      最近更新 更多