gpt4 book ai didi

angular - 从映射生成类型/接口(interface)列表

转载 作者:行者123 更新时间:2023-12-05 03:18:12 28 4
gpt4 key购买 nike

给定以下对象:

const ROUTES = {
PAGE_NO_PARAMS: '/hello/page/two',
PAGE_R: '/about/:id',
PAGE_Z: '/page/page/:param/:id',
PAGE_N: '/who/:x/:y/:z/page',
} as const

是否可以为每个 route 提供类型/接口(interface)列表,以便开发人员只能使用所选路由的有效参数。

即。从 ROUTES 生成一个类型,其结果与下面的 type RouteAndParams 相同。

interface PageNoParams = {
route: '/hello/page/two' // no params
}

interface Param1 = {
route: '/about/:id',
params: { id: string } // required params
}

interface PAGE_Z = {
route: '/page/page/:param/:id',
params: { id: string; param: string } // required params
}

interface Param3 = {
route: '/who/:x/:y/:z/page',
params: { x: string; y: string; z: string } // required params
}

type RouteAndParams = PageNoParams | Param1 | PAGE_Z | Param3;

// Some examples of expected results / errors when using generated type

// should NOT error
const routeWithParams: RouteAndParams = {
route: '/page/page/:param/:id',
params: { 'param': 'blah', 'id': 'xxx' }
}

// should error as unexpected param 'x'
const routeWithParams: RouteAndParams = {
route: '/about/:id',
params: { 'id': 'xxx', 'x': 'xxx' }
}

// should error as param 'y' is missing
const routeWithParams: RouteAndParams = {
route: '/who/:x/:y/:z/page',
params: { 'x': 'blah', 'z': 'blah' }
}

我希望这一切都有意义。我正在尝试用构建错误替换运行时错误。

最佳答案

您可以使用一些递归条件类型来处理路径并从每个路径中提取参数:


type Routes = MakeValidRoute<typeof ROUTES[keyof typeof ROUTES]>
// = "/hello/page/two" | `/about/${string}` | `/page/page/${string}/${string}` | `/who/${string}/${string}/${string}/page`

type GetInterfaceKeys<T extends string, R extends string = never> =
T extends `${string}/:${infer Name}/${infer Tail}`?
GetInterfaceKeys<`/${Tail}`, R | Name>:
T extends `${string}/:${infer Name}`?
R | Name:
R

type MakeRouteAndParams<T extends Record<string, string>> = {
[P in keyof T]: {
route: T[P],
params: Record<GetInterfaceKeys<T[P]>, string>
}
}[keyof T]

type RouteAndParams = MakeRouteAndParams<typeof ROUTES>
// type RouteAndParams = {
// route: "/hello/page/two";
// params: Record<never, string>;
// } | {
// route: "/about/:id";
// params: Record<"id", string>;
// } | {
// route: "/page/page/:param/:id";
// params: Record<"id" | "param", string>;
// } | {
// ...;
// }

Playground Link

我们使用尾递归条件类型来提高这些类型在编译器中的性能

关于angular - 从映射生成类型/接口(interface)列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73804290/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com