I have a list of routes:
export interface RouteMap {
routeA: string;
routeB: string;
routeC: string;
...
}
const routesMap: RouteMap = {
routeA: 'route-a-url',
routeB: 'route-b-url/:param',
routeC: 'route-c-url/:some-id/data',
...
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
and a Proxy
to object that could handle methods:
- getRouteNameUrl(...arg: any[]): string;
- goToRouteNameUrl(...arg: any[]): void;
- probably some other dynamic boilerplate stuff
i.e. getRouteAUrl, getRouteBUrl and so on.
the question is:
Is there a way to describe the Proxed object, that is based on some interface/class type's modified properties in typescript?
something like this
type ProxedRouteMap<T> = {
[get`[P in keyof T]`Url]: (...arg: string[]) => string;
[goTo`[P in keyof T]`]: (...arg: string[]) => void;
...
}
const routeMapService: ProxedRouteMap<RouteMap> = new Proxy(routeMap, {
apply(target, thisArg, ...args) {
...
}
});
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Yes, you can use as
clause in mapped type through which a transformation of the generated property names can be specified:
type ProxedRouteMap<T> = {
[P in keyof T as `get${Capitalize<string & P>}Url`]: (...arg: string[]) => string;
} & {
[P in keyof T as `goTo${Capitalize<string & P>}`]: (...arg: string[]) => void;
}
/**
* {
* getRouteAUrl: (...arg: string[]) => string;
* getRouteBUrl: (...arg: string[]) => string;
* getRouteCUrl: (...arg: string[]) => string;
* } & {
* goToRouteA: (...arg: string[]) => void;
* goToRouteB: (...arg: string[]) => void;
* goToRouteC: (...arg: string[]) => void;
* }
*/
type Foo = ProxedRouteMap<RouteMap>
Or even simpler:
type ProxedRouteMap<T> = {
[P in `get${Capitalize<keyof T & string>}Url`]: (...arg: string[]) => string;
} & {
[P in `goTo${Capitalize<keyof T & string>}`]: (...arg: string[]) => void;
}