我认为我可能会碰到带有Typescript的打开错误(https://github.com/microsoft/TypeScript/issues/21760),但是我正在有效地尝试找出如何从其他文字常量创建映射的文字类型。
从下面的lodash函数中考虑正确的索引键入结果。
const result = _.mapKeys(en,x => x.display);
export const en = {
ACTIVE: {
ordinal: 0,
display: 'Active',
},
INACTIVE: {
ordinal: 1,
display: 'Inactive',
},
} as const;
// how do i type this?
export const displayToEnum = {};
// actual runtime implementation code
for (const key in en) {
displayToEnum[en[key].display] = en[key];
}
// What i've tried
type Displays = typeof en[keyof typeof en]['display']
type DisplayToEnum = {
// how do i do this dynamically - find the mapped item which fits the conditional constraint
[P in Displays]: P extends typeof en['ACTIVE']['display'] ? typeof en['ACTIVE'] : typeof en['INACTIVE'];
}
export const displayToEnum: DisplayToEnum = {} as any;
for (const key in en) {
displayToEnum[en[key].ordinal] = en[key];
}
// its hardcoded, but this resolves correctly to 0.
const value = displayToEnum['Active'].ordinal;
答案 0 :(得分:1)
您可以使用Extract
根据当前属性en
过滤P
的值
export const en = {
ACTIVE: {
ordinal: 0,
display: 'Active',
},
INACTIVE: {
ordinal: 1,
display: 'Inactive',
},
} as const;
type En = typeof en
type DisplayEnum = {
[P in En[keyof En]['display']]: Extract<En[keyof En], { display: P }>
}
或者您可以使用类似UnionToIntersection
的方式从联合中构建类型,其中每个成员包含一个与display
相同名称的属性
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
type DisplayEnum2 = UnionToIntersection<{
[P in keyof En]: Record<En[P]['display'], En[P]>
}[keyof En]>;