My goal is to have a function that takes a key and an object with query parameters and the function can look up a URL, interpolate with the query params and navigate to that. What I got so far is this
interface FooIdParams {
fooId: number;
}
interface QueryParams<P = never> {
params: P;
}
enum Urls {
'foo-editor' = '/editfoo?fooId=${fooId}'
}
interface ParamTypes {
'foo-editor': QueryParams<FooIdParams>
}
and the load method in my class looks like this:
load = <T extends keyof ParamTypes>(target: T, params: ParamTypes[T]["params"]):void => {
const url = eval('`' + Urls[target] + '`')
// alternative with replace like suggested in a comment
// this also works with multiple query params
const url2 = Urls[target].replaceAll(/\$\{(.*?)\}/g, (_: string, k: string) => (params as any)[k])
// and some code to open that page
}
This already works and ensures that the called provides correct query params (later I have dozens of URL targets and the load method is called from many places, so it's worth the effort)
The part that I can't solve: I use the key foo-editor in two different places, the enum where it maps to the 'url' and in the interface, where it maps to the type. And I'd like to guarantee, that both enum and interface have exactly the same keys (like - typescript should force to mappings in both and prevent typos).
Is there a way to ensure that?
evalI'd really use.replace(/\$\{(.*)\}/g, k => params[k]);k- typescript complains.anysimplifies things (playground)paramsis guaranteed to be of the correct type and will have all required keys. Thanks!kin your code is the full match - second one is the captured value that we want. And then, it only works with one param, because the regexp is greedy by default. I edit my question and put the working alternative in it. Thanks for at least pointing me into that direction!