【发布时间】:2020-12-13 23:10:03
【问题描述】:
假设我们有两个接口A 和B:
interface A {
width: number;
height: number;
label: {
text: string;
};
navigator: {
min: number;
max: number;
}
}
interface B {
width: number;
height: number;
label: {
text: string;
formatter: (text: string) => string;
};
radius: number;
}
我可以像这样手动指定所需的通用形状:
interface AB { // ????????
width: number;
height: number;
label: {
text: string;
};
}
但理想情况下,我希望类型系统能够像这样自动计算出形状:
type AB = A & B; // ????????
显然,type AB 不具有interface AB 的预期形状。
有什么想法吗?
编辑:一个示例用例:
const defaultTheme: AB = {
common: { // default values for properties common to A and B
width: 800,
height: 400,
label: {
text: 'Title'
}
},
A: { // missing defaults will come from `common`
navigator: {
min: 0,
max: 1
}
},
B: { // missing defaults will come from `common`
label: {
formatter: (text: string) => '$' + text
},
radius: 50
}
};
// The user would configure a component in a declarative fashion:
const userConfig = {
theme: defaultTheme,
items: [{
type: 'A',
height: 600,
navigator: {
min: 0.5
}
}, {
type: 'B',
label: {
text: 'My Custom Title'
}
}]
}
因此用户未明确指定的项目属性将来自默认主题。
【问题讨论】:
-
递归执行此操作 (
label) 将非常棘手。如果只是这两个,交叉类型不工作吗?您可以使用类型的公共部分而不区分它们,但是如果您区分它们(例如,使用警卫),则每个完整类型都可用。关闭这种可能性的类型AB的用例是什么? -
我必须删除 cmets 以使其适合 SO 注释,因此:(1) = 使用公共部分。 (2) 当且仅当您需要使用 A 或 B 的特定部分时,一旦确定了您所拥有的,您就可以使用。 (3) 这是一个 A。 (4)。这是一个 B。
-
@T.J.Crowder 谢谢。例如,如果库用户想要指定应用于项目数组中所有对象的通用属性,而不必将这些属性合并到每个项目的配置中。如果可以使用类型系统来指导用户哪些属性对每种项目类型有效,我会很好。
-
@T.J.Crowder 哈哈,这很公平,我认为这可能是答案,但我有希望 :) 感谢您的回复!
标签: typescript types interface intersection