从Partial <t>扩展的Typescript接口为想要扩展T的扩展接口带来了钻石问题

时间:2019-03-06 06:09:37

标签: typescript

我正在尝试为一种类型扩展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。但是,我可以像这样定义Text来覆盖扩展接口,而无需扩展Button

interface Button extends ButtonStyles {
    text: string;
}

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

2 个答案:

答案 0 :(得分:0)

映射类型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

答案 1 :(得分:0)

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

因为您有这种要求,所以覆盖字段类型没有问题。 “ Button”是从ButtonStyles收集的另一种类型,但也有所不同。

interface Text {
    text: string;
}

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

//Overeriding the optional text field
interface Button extends ButtonStyles {
    text: string
}