【问题标题】:Typescript interface extend from Partial<T> creates diamond problem for extended interfaces wanting to also extend TTypescript 接口从 Partial<T> 扩展为想要扩展 T 的扩展接口创建菱形问题
【发布时间】:2019-03-06 06:09:36
【问题描述】:

我正在尝试为一种类型扩展 Partial 接口,但这使我无法要求扩展原始类型的任何接口中已经提供的字段。

例子:

interface Text {
    text: string;
}

interface ButtonStyles extends Partial<Text> {
    isBold?: false;
}

// is this a variant of the diamond problem?
interface Button extends ButtonStyles, Text {}

这会产生error TS2320: Interface 'Button' cannot simultaneously extend types 'ButtonStyles' and 'Text'1。但是,我可以通过像这样定义Button 来覆盖接口而不扩展Text

interface Button extends ButtonStyles {
    text: string;
}

我真正想要的是拥有ButtonStyles 不需要text 属性,而是允许它-同时还强制Button 实现具有text 属性。是否有更合适的方法可以将属性提取为基本接口的可选属性,同时让它们用于扩展接口?这个问题有名字吗?

【问题讨论】:

  • 那么interface Button extends ButtonStyles { text: string; } 有什么问题?
  • 这是一个非常简单的例子。让我们假设 Text 有几个我想要的属性,我想让更改 Text 的定义变得非常容易,并将这些更改轻松传递给我的所有按钮和其他扩展类型。

标签: typescript


【解决方案1】:

映射类型 allow 用于从道具中添加或删除可选的 (?) 修饰符。因此,您可以添加一个实用程序,使指定的密钥成为必需:

interface Text {
    text: string;
}

interface ButtonStyles extends Partial<Text> {
    isBold?: boolean;
}

type WithRequired<T, TKeys extends keyof T> = T & { [P in TKeys]-?: T[P] };

type Button = WithRequired<ButtonStyles, keyof Text>;

const button: Button = { } // Error - Property 'text' is missing ...

Playground

【讨论】:

    【解决方案2】:

    下面的代码将是正确的方法之一!

    覆盖字段类型没有问题,因为您对此有要求。 “按钮”是另一种从 ButtonStyles 中收集的类型,但也与它不同。

    interface Text {
        text: string;
    }
    
    interface ButtonStyles extends Partial<Text> {
        isBold?: false;
    }
    
    //Overeriding the optional text field
    interface Button extends ButtonStyles {
        text: string
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-26
      • 2018-06-20
      • 2020-09-07
      • 2021-08-16
      • 2015-06-21
      • 2020-10-30
      • 2020-06-09
      相关资源
      最近更新 更多