[英]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.