簡體   English   中英

TypeScript - 將動態屬性名稱傳遞給子級

[英]TypeScript - Pass Dynamic Property Name to Children

我正在開發一個帶有嵌套路由的路由庫,我正在嘗試定義一個子處理程序 function 來推斷父路徑。 原因是我有另一種可以從字符串推斷動態路徑參數的類型(例如, users/:id{ id: string } ); 因此,我希望能夠將推斷的路徑參數從父路由傳遞到每個子路由處理程序 function 中的任何和所有子路由。

這是我到目前為止所擁有的:

type RawRouterDefn<Namespace extends string = ""> = {
    [K: string]: Handler<Namespace, typeof K> | RawRouterDefn<`${Namespace}/${typeof K}`>;
};

type Handler<DataPath extends string, Path extends string> = ((args: { dataPath: DataPath, path: Path }) => unknown)

type Router<Routes extends RawRouterDefn, DataPath extends string = ""> = {
    [K in keyof Routes & string]: Routes[K] extends CallableFunction
        ? Handler<DataPath, K>
        : Router<Routes[K], `${DataPath}/${K}`>;
};

function createRouter<T extends RawRouterDefn>(rawDefn: T): Router<T, ""> {
    // Implementation not important right now
    return {} as unknown as Router<T, "">
}

const router = createRouter({
    some: {
        deeply: {
            nested: {
                /**
                 * Here, dataPath should be inferred as `some/deeply/nested`,
                 * path should be `route`
                 */
                route: ({ dataPath, path }) => {}
            },
        },
    },
});

const route = router.some.deeply.nested.route;
// Correctly inferred **after** function applied, I need it within the router definition
type Params = Parameters<typeof route>[0]

(以及游樂場的鏈接

我快到了,除了dataPath應該被推斷為/some/deeply/nested而不是/${string}/${string}/${string}並且path應該被推斷為/route而不是/${string} . 這表明我在RawRouterDefn類型中缺少一些東西。

所以看起來我可以正確地縮小字符串的形狀,但我目前的方法沒有進一步。

同樣,當用作 function arguments 時,我需要推斷它,而不是之后。

非常接近,只需要用 generics 做一點魔法:

function createRouter<T extends RawRouterDefn, R extends Router<T, "">>(rawDefn: R): R {

現在它可以工作了: https://tsplay.dev/NDRE1W

您需要另一個泛型來告訴 TypeScript 您在 function 中得到的正是您返回的。 刪除T extends RawRouterDefn並使用R extends Router<RawRouterDefn, "">會破壞推理,所以,不要這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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