【发布时间】:2021-05-10 21:53:27
【问题描述】:
可能有更好的方法来命名这个问题。如果你想到一个更好的名字,请告诉我,我会更改标题。我的问题有点复杂,但我有a code sample that demonstrates what I'm looking for well:
type Category = "FooAndBar" | "JustBaz" | "All"
export const widgets = [
{
name: 'Foo',
categories: ["FooAndBar", "All"]
},
{
name: 'Bar',
categories: ["FooAndBar", "All"]
},
{
name: 'Baz',
categories: ["JustBaz", "All"]
},
] as const;
export type WidgetName = typeof widgets[number]['name'];
export interface Widget {
name: WidgetName;
categories: Category[]
}
export interface WidgetPrices {
location: string;
// some field here that requires you to cover every type of widget,
// whether it be from categories or specific names
}
// Here's how I would want WidgetPrices to work:
const valid = {
location: "qazlandia",
Foo: 1,
Bar: 2,
Baz: 3,
}
const valid2 = {
location: "qazlandia",
FooAndBar: 3,
Baz: 3,
}
const valid3 = {
location: "qazlandia",
All: 10,
}
const valid4 = {
location: "qazlandia",
FooAndBar: 3,
Bar: 5, // in code, I would probably give a specific name precedence over a category, but Foo would fallback to its category
Baz: 3,
}
const valid5 = {
location: "qazlandia",
FooAndBar: 3,
All: 5, // in code, I would probably give a specific category precedence over a broader category
}
const valid6 = {
location: "qazlandia",
FooAndBar: 3,
JustBaz: 5,
}
const error = {
location: "qazlandia",
Foo: 1,
// error: missing bar
Baz: 3,
}
const error2 = {
location: "qazlandia",
FooAndBar: 3,
// error, missing baz
}
问题是,可以用 typescript 的类型系统来定义这样的东西吗? WidgetPrices' 的声明是什么样的?
我在某些方面对 WidgetPrices' 声明很灵活,例如,我更喜欢实现看起来像我呈现的方式,但我可以单独使用 Names和Category 属性,如果这是解决这个问题的唯一方法。对我来说最重要的是当我错过覆盖范围时编译器会出错。
【问题讨论】:
-
嗨,您是否有任意数量的字段要添加到小部件价格中?在这种情况下,我会添加一个通用的可选参数,例如 [_: string] :?任何。如果您可以添加有限数量的价格类型,我会从小部件价格扩展它们。最后,您可以考虑使用类型为 T 的 params 属性的类型化 wodgetPrices
-
每次我向
widgets添加一个新元素时,WidgetPrices都会得到一个新字段。我不知道这是不是你要问的,@CarlosMoura -
这是我为之而生的问题。
标签: typescript