簡體   English   中英

在 TypeScript 中將遞歸數組/對象返回為展平的 object 類型

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM