[英]TypeScript template literal string from nested object
我想得到这个 object 类型中所有states
下的键的联合,
我有一个嵌套的 object state
键。 我想以点表示法获得state
下所有这些键的联合。
例如,对于这个配置:
type Config = {
initial: string;
states: {
idle: {
on: {
START: string;
};
};
running: {
on: {
PAUSE: string;
};
};
paused: {
initial: string;
states: {
frozen: {
on: {
HEAT: string;
};
};
};
on: {
RESET: string;
};
};
};
我想要'idle' | 'running' | 'paused' | 'paused.frozen'
'idle' | 'running' | 'paused' | 'paused.frozen'
这可能吗? 有任何想法吗?
type StatesKeys<T> = T extends { states: infer S } ? {
[K in Extract<keyof S, string>]: K | `${K}.${StatesKeys<S[K]>}`
}[Extract<keyof S, string>] : never
type ConfigStatesKeys = StatesKeys<Config>;
// type ConfigStatesKeys = "idle" | "running" | "paused" | "paused.frozen"
StatesKeys<T>
检查T
的states
属性S
,并为它的每个键K
生成我们想要的联合,即K
本身,加上K
与点和StatesKeys<S[K]>>
的可能连接。 也就是说,我们将每个键K
与来自S[K]
的任何嵌套键连接起来。 如果没有嵌套键,且StatesKeys<S[K]>
为never
,则模板文字也将变为never
,因此我们不必对其进行特殊处理。
您可以使用这样的递归条件类型来执行此操作:
type StateKeys<T> = T extends {states: infer S}
? keyof S | StateKeys<S[keyof S]>
: never
type Test = StateKeys<Config>
// type Test = "idle" | "running" | "paused" | "frozen"
啊,我错过了您需要paused.frozen
而不是frozen
。 对于它的价值,我的旧解决方案可以像这样修复,只使用条件类型:
type StateKeysForKey<S, K> = K extends keyof S & string
? `${K}.${StateKeys<S[K]>}`
: never
type StateKeys<T> = T extends {states: infer S}
? keyof S | StateKeysForKey<S, keyof S>
: never
type Test = StateKeys<Config>
// type Test = "idle" | "running" | "paused" | "paused.frozen"
您可以使用keyof
关键字,在您的特定示例中,一种解决方案可能是keyof states
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.