[英]Return recursive array/object as flattened object type in TypeScript
我正在嘗試編寫一個 function ,它采用遞歸對象/數組,其中每個節點都有一個“名稱”,也可以選擇“孩子”。 然后我想要一個 function ,它采用這種遞歸結構並返回一個類型安全的 object ,其中遞歸出現的“名稱”是鍵,節點是值; 因此,如果您嘗試訪問不存在的密鑰,它會在編譯期間為您出錯。
到目前為止,我能夠以這種方式識別頂級名稱(名稱“a”和“b”),以便將flat
識別為Record<"a" | "b", RouteConfigItem<"a" | "b">>
Record<"a" | "b", RouteConfigItem<"a" | "b">>
Record<"a" | "b", RouteConfigItem<"a" | "b">>
。
type RouteConfigItem<Keys> = {
name: Keys;
path: string;
children?: Array<RouteConfigItem<Keys>>;
}
type RouteConfig<Keys> = RouteConfigItem<Keys>[];
function getFlat<Keys>(routeConfig: RouteConfig<Keys>): Record<Keys, RouteConfigItem<Keys>> {
// Implementation doesn't matter.
return routeConfig as Record<Keys, RouteConfigItem<Keys>>;
}
const flat = getFlat([{
name: 'a',
path: 'a',
}, {
name: 'b',
path: 'b',
children: [{
name: 'c',
path: 'c',
}]
}] as const);
但是我怎樣才能讓它也看到非頂級名稱呢? 只關心類型,而不關心getFlat()
主體中的實現,我希望flat
被識別為Record<"a" | "b" | "c", RouteConfigItem<"a" | "b" | "c">>
Record<"a" | "b" | "c", RouteConfigItem<"a" | "b" | "c">>
Record<"a" | "b" | "c", RouteConfigItem<"a" | "b" | "c">>
.
順便說一句,代碼示例在我的 WebStorm 中似乎對我有用,但在 typescriptlang.org/play 中似乎不起作用,所以我沒有包含這樣的鏈接。
我稍微簡化了RouteConfig
的定義:
type RouteConfig = {
name: string,
path: string,
children?: ReadonlyArray<RouteConfig>
};
現在要提取密鑰,您可以:
type ExtractKeys<R extends RouteConfig> = R extends { children: ReadonlyArray<RouteConfig> }
? R['name'] | ExtractKeys<R['children'][number]>
: R['name'];
function 簽名將是:
function getFlat<R extends RouteConfig>(routeConfig: readonly R[]):
Record<ExtractKeys<R>, RouteConfig> {
// Implementation doesn't matter.
return routeConfig as any;
}
const flat = getFlat([{
name: 'a',
path: 'a',
}, {
name: 'b',
path: 'b',
children: [{
name: 'c',
path: 'c',
}]
}] as const); // Record<"a" | "b" | "c", RouteConfig>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.