如何按属性类型忽略类型

时间:2019-07-15 17:11:19

标签: typescript

我有一个类型,其中某些属性键入了字符串,数字等...,我想省略一些类型不是字符串的属性。

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,但没有将其删除。

1 个答案:

答案 0 :(得分:1)

这里的解决方案是获取与所需属性值相对应的键的并集,然后Pick。这是一种实现方法:

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

KeysMatching<T, V>使用mappedconditionallookup类型查找类型为{{1}的键,其属性值可分配为类型{{1 }}。

然后,我们可以制作T,这些V就是这些值:

PickMatching<T, V>

Pick只会在type PickMatching<T, V> = Pick<T, KeysMatching<T, V>>; 值的属性上使用PickAbility<T>(您的示例代码使用PickMatching,但是您的Function方法都不匹配):

(payload: {}) => Promise<{}>

让我们测试一下:

Person

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

Link to code