我要做的是定义某种“富枚举”,其中每个枚举键都链接到一些我想指定其类型的数据。
例如,就像这样:
const Seasons = {
winter: { temperature: 5, startMonth: "December" },
spring: { temperature: 20, startMonth: "March" },
summer: { temperature: 30, startMonth: "June" },
fall: { temperature: 15, startMonth: "September" },
} as const这个声明很好,让我可以做如下事情:
type Season = keyof typeof Seasons // "winter" | "spring" | "summer" | "fall"甚至是像这样的类型守卫
function isSeason(s: string): s is Season {
return Object.keys(Seasons).includes(s)
}然而,我不能做的是让编译器检查所有的“季节定义”是否都有一个给定的类型。如果我这样定义:
type SeasonData = typeof Seasons[Season]那么SeasonData就是所有定义类型的联合--不管它们是否具有相同的形状。
因此,我正在寻找一种语法上无冗余且轻量级的方式来定义如下内容:
const Seasons: EnumWith<{temperature: number, startMonth: string}> = ... // as before
^^^^^^^^ <- to be defined!特别是,我尽量不在任何其他结构(接口或数组)中重复季节列表,而是直接从对象定义中推断Season类型(尽管听到alternative总是不错的!)。
可以做些什么呢?
发布于 2020-06-25 18:02:51
我不确定我是否完全理解您的用例,我对您的类型之间的关系建模的方式如下所示
type Season =
| "winter"
| "spring"
| "summer"
| "fall"
type Month =
| "January"
| "February"
| "March"
| "April"
| "May"
| "June"
| "July"
| "August"
| "September"
| "October"
| "November"
| "December"
type SeasonStruct = {
temperature: number
startMonth: Month
}
type Seasons = { [K in Season]: SeasonStruct }
const seasons: Seasons = {
winter: { temperature: 5, startMonth: "December" },
spring: { temperature: 20, startMonth: "March" },
summer: { temperature: 30, startMonth: "June" },
fall: { temperature: 15, startMonth: "September" },
}这将为您提供足够的构建块来表示您的域中所需的所有内容,希望它能有所帮助。
发布于 2020-06-25 18:22:19
我刚刚找到了一种从键中提取文字类型信息,同时仍然检查值的有点复杂的方法:
function EnumWith<P>() {
return function <K extends keyof any, R extends Record<K, P>>(defs: R): R {
return defs
}
}它允许这样写:
const Seasons = EnumWith<{
temperature: number
startMonth: Month // defined as in bugs's answer
}>()({
winter: { temperature: 5, startMonth: "December" },
spring: { temperature: 20, startMonth: "March" },
summer: { temperature: 30, startMonth: "June" },
fall: { temperature: 15, startMonth: "September" },
})
type Season = keyof typeof Seasons关键是发现K extends keyof any允许您捕获泛型签名中的键的类型,并将两个泛型类型划分为两个函数调用,以便我们可以指定一个并推断另一个(目前在TypeScript中的单个函数调用中是不可能的)。
因此,诚然,}>()({这行代码有点难看…
https://stackoverflow.com/questions/62572358
复制相似问题