【问题标题】:How can I extract the names of all fields of a specific type from an interface in Typescript?如何从 Typescript 的接口中提取特定类型的所有字段的名称?
【发布时间】:2018-06-24 04:15:28
【问题描述】:

假设我有一个这样的界面:

interface SomeInterface {
    field1: string;
    field2: number;
    field3: string;
    field4: SomeOtherType;
}

我想要一种类型,可以提取所有键的值是特定类型的:

type ExtractFieldsOfType<Obj extends {}, Type> = // implementation

ExtractFieldsOfType<SomeInterface, string> // "field1" | "field3"
ExtractFieldsOfType<SomeInterface, number> // "field2"
ExtractFieldsOfType<SomeInterface, SomeOtherType> // "field4"

这样写可以吗?我正在编写一个按键名对对象进行操作的函数,但它应该只允许具有特定值的键。所以最好通过类型系统来表达。

【问题讨论】:

  • 简单地用作地图。

标签: typescript


【解决方案1】:

您可以在 TypeScript 2.8 中使用条件类型来实现。

我创建了支持类型AllowedFieldsWithType 以进行更简洁的实现。

type AllowedFieldsWithType<Obj, Type> = {
    [K in keyof Obj]: Obj[K] extends Type ? K : never
};

type ExtractFieldsOfType<Obj, Type> = AllowedFieldsWithType<Obj, Type>[keyof Obj]

type StringFields = ExtractFieldsOfType<SomeInterface, string> // "field1" | "field3"
type NumberFields = ExtractFieldsOfType<SomeInterface, number> // "field2"
type ObjectFields = ExtractFieldsOfType<SomeInterface, SomeOtherType> // "field4"

它是如何工作的?

第一种:

type AllowedFieldsWithType<Obj, Type> = {
    [K in keyof Obj]: Obj[K] extends Type ? K : never
};

1) 对于对象中的每个字段,我们检查它是否扩展了类型,然后我们返回键的名称作为它的类型。如果不是(例如,我们搜索 string,但 field2number 类型 - 我们返回 never。这是一种特殊类型,无法分配任何内容。

AllowedFieldsWithType<SomeInterface, String> equals to: {
  field1: 'field1';
  field2: never;
  field3: 'field3';
  field4: never;
}

2) 然后我们必须过滤掉never 属性,我们可以使用Pick 来完成,但是对于这个用例,我们只需要键名。

3) 最终我们使用someType[keyof Obj] 收集给定类型的值,从不跳过。

我写过一篇文章深入解释了这个话题:Create a condition-based subset types

【讨论】:

  • 您不需要额外的选择来过滤掉永远不会出现的A|never=A。这也可以输入ExtractFieldsOfType&lt;Obj, Type&gt; = AllowedFieldsWithType&lt;Obj, Type&gt;[keyof Obj]
  • @TitianCernicova-Dragomir 确实是的,对于这个用例,我们不必使用Pick :) 我简化了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 2021-01-13
  • 1970-01-01
  • 2019-08-27
  • 1970-01-01
  • 2020-11-27
  • 1970-01-01
相关资源
最近更新 更多