我不认为
enum
“现在事情是可能的。即使可以,也无法从
Features
类型(即
要素
的
特征
枚举)到
typeof Features
类型
映射
从键到
特征
元素)不知道
特征
首先。再次说明:类型
Features.B
例如,对字符串文字一无所知
"B"
. 只有
功能类型
有这样的财产
{B: Features.B}
. 如果要从类型函数转换
特征
到
Features | keyof typeof Features
,你需要提到
功能类型
明确地。所以即使你有梦想
extends enum
注意,您仍然需要用您关心的映射列表来编写替换代码。对不起的。
只处理递归部分,以防发生问题,下面是我如何递归处理类型以替换
已知的
具有枚举值和相关键的联合的枚举值:
enum Features {
"A" = 1,
"B" = 2,
"C" = 2
}
type ValueOf<T> = T[keyof T]
type FeatureKey<T extends Features> =
Extract<ValueOf<{
[K in keyof typeof Features]: [K, typeof Features[K]]
}>, [any, T]>[0]
type DeepFeaturesOrKey<T> =
T extends Features ? (T | FeatureKey<T>) :
T extends Array<infer L> ? DeepFeaturesOrKeyArray<L> :
T extends object ? { [K in keyof T]: DeepFeaturesOrKey<T[K]> } : T
interface DeepFeaturesOrKeyArray<L> extends Array<DeepFeaturesOrKey<L>> { }
如果不指定整个枚举(例如,使用
discriminated union
输入一个特定的枚举值),当然,整个深度任意数组的欺骗,以避免提到可怕的“循环引用”错误消息。
here
:
与联合和交集类型类似,条件类型不允许递归引用自己(但是,允许通过接口类型或对象文本类型间接引用)。
让我们测试一下:
interface Foo {
bar: string,
baz: Features,
qux: {
a: Features[],
b: boolean
},
quux: Features.A,
quuux: Features.B
}
type DeepFeaturesOrKeyFoo = DeepFeaturesOrKey<Foo>
declare const deepFeaturesOrKeyFoo: DeepFeaturesOrKeyFoo
deepFeaturesOrKeyFoo.bar; // string
deepFeaturesOrKeyFoo.baz; // Features | "A" | "B" | "C"
deepFeaturesOrKeyFoo.qux.a[1]; // Features | "A" | "B" | "C"
deepFeaturesOrKeyFoo.qux.b; // boolean
deepFeaturesOrKeyFoo.quux; // Features.A | "A"
deepFeaturesOrKeyFoo.quuux; // Features.B | "B" | "C"
// note that the compiler considers Features.B and Features.C to be the
// same value, so this becomes Features.B | "B" | "C"
看起来不错。希望有帮助。