繁体   English   中英

Typescript 可选扩展接口

[英]Typescript optionally extending interface

我有两个interfaces ,其中一个扩展了另一个。 但是,我希望能够扩展第一个interface并使其所有类型成为可选的。 我不想在我的第二个interface中将第一个interface的所有定义重写为可选(因为此时扩展的优势是什么?)或者重新定义第一个interface ,因为它正在别处使用。

它看起来像什么:

interface First {
  type1: string
  type2: string
}

// Seemingly pointless rewrite (why would I even need to extend?)
interface Second extends First {
  type1?: string
  type2?: string
  type3: string
  type4: string
}

// What I imagine the extending should be (but doesn't work)
interface Second extends First? {
  type3: string
  type4: string
}

我做了我的研究,确实发现这个问题回答了一些非常相似的问题,但是自从触及这个问题已经一年了,我认为我的问题并不完全相同,因为我想让整个扩展interface成为可选的,而不仅仅是一个它的几种类型。

在 Typescript 中有什么方法可以做到这一点,还是我只需要吸收它并制作一个长的第二个interface


更新(解释为什么我想要这项工作):

我正在编写一个 React web 应用程序,并且有一个组件以允许用户编辑该实体的任何值的方式显示我的数据库中的实体。 我希望我的 React 组件能够处理用户正在创建新实体的情况,以及用户正在编辑现有实体的情况。

为了与我上面的示例保持一致,假设我的数据库实体的值由First interface复制,并且 React 组件使用存在于Second interface中的两个传递的道具。 React 组件将始终具有Second中的两个值,但不一定具有First中的值。

在用户创建新实体的情况下,我想仅使用Second的值构建 React 组件,而不必为First中的所有内容指定null值。 在用户编辑现有实体的情况下,我会传递FirstSecond中的所有内容。

在这两种情况下,它都是相同的 UI,但使用不同的值集构建。

您可以将类型别名Partial类型的交集一起使用:

type First = {
    type1: string;
    type2: string;
}

type Second = Partial<First> & {
    type3: string;
    type4: string;
}

您可以使用Partial类型对接口执行此操作。

interface First {
    type1: string;
    type2: string;
}

interface Second extends Partial<First> {
    type3: string;
    type4: string;
}

有更好/更简单的方法。 使用省略,您可以仅重新定义特定的命名属性。

interface First {
    type1: string;
    type2: string;
}

interface Second extends Omit<First, "type1"> {
    type1?: string;
}

您还可以通过提供一个空的接口来使所有部分成为可选的:

export interface ISingleScope {
   scope: string;
}

export interface IMultiScope {
   scopes: string[];
   check?: boolean;
}

export interface IProvidedScope 
   extends Partial<ISingleScope>, Partial<IMultiScope> { 
}

但是,通常这需要对使用的属性进行显式测试,因为在运行时这些信息都不存在。 因此,如果您的对象带有名称选项,那么这就足够了:

if (options && options.scopes) {
   // access properly 'IMultiScope'
}

Partial很棒,但有时您想要选择要设为可选的键,而不是将它们全部设为可选!

为此,请使用: type Optional<T, K extends keyof T> = Partial<Pick<T, K>> & Omit<T, K>

资料来源:如果您需要嵌套可选,go 链接问题,则此可选答案来自问题。

在 Typescript interface Extends意味着第二个对象将继承第一个对象所拥有的任何内容,如果第一个对象的属性是可选的,则它们将不加更改地应用于第二个对象。 您无法在 Typescript 中更改此行为。 您不应该对您的情况使用extends问题的答案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM