Home > Back-end >  Is there a way to describe type for Proxy based on modified properties in typescript
Is there a way to describe type for Proxy based on modified properties in typescript

Time:11-17

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>

Playground


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;
  }
  • Related