如何通过扩展从TypeScript接口中删除字段

ffx*_*sam 8 typescript

假设有一个我无法控制的界面:

interface Original {
  name: string;
  size: number;
  link: SomeType;
}
Run Code Online (Sandbox Code Playgroud)

我想扩展这个接口,但实际上删除 link所以我最终得到一个有效的新接口:

interface OriginalLite {
  name: string;
  size: number;
}
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

jca*_*alz 22

您可以使用映射条件类型来实现此目的.通常我们称之为您要做的事情Omit:

type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
Run Code Online (Sandbox Code Playgroud)

所以Omit<T, K>基本上是相同T但没有任何属性K.您可以执行以下操作以创建仅缺少的新interface调用:OriginalLitelink

interface OriginalLite extends Omit<Original, 'link'> {}
Run Code Online (Sandbox Code Playgroud)

请注意,您没有扩展 Original.这是因为TypeScript中的"扩展"意味着使类型更具体(又称"缩小"),但在您的情况下,您正在做的是使其不那么具体(也就是"加宽").所以这就是为什么extends Original没有出现在那个定义中.我认为你没关系.

我们来测试一下:

declare const originalLite: OriginalLite;
originalLite.name; // string
originalLite.size; // number
originalLite.link; // error, property 'link' does not exist on type 'OriginalLite'
Run Code Online (Sandbox Code Playgroud)

看起来不错.希望有所帮助.祝好运!

  • 对于希望排除多个属性的人来说,这将是:`interface OriginalLite extends Omit&lt;Original, 'link'|'size'&gt; {}` (39认同)
  • 以下是所有实用程序类型的列表:https://www.typescriptlang.org/docs/handbook/utility-types.html (2认同)

Cov*_*vik 9

只是补充一下:如果您没有要删除的键列表,而只有可用于keyof获取键列表并忽略它们的界面。

例子:

interface RemoveThoseKeys {
  removeMe1: unknown
  removeMe2: unknown
}

interface AllKeys {
  keep1: unknown
  keep2: unknown
  removeMe1: unknown
  removeMe2: unknown
}

type KeysAfterRemoval = Omit<AllKeys, keyof RemoveThoseKeys>
Run Code Online (Sandbox Code Playgroud)

如果您使用类型实例化一个对象KeysAfterRemoval并在 IDE 中点击自动完成,您应该只得到keep1keep2

IDE 自动完成


Sha*_*hah 8

从类型中省略多个不需要的属性并添加新的自定义属性的示例。

type UnwantedKeys = "key1" | "key2"

interface MyNewType extends Omit<Original, <UnwantedKeys>> {
  newProp1: string
  newProp2: number
}
Run Code Online (Sandbox Code Playgroud)