Javascript Typescript-键到类型和值的类型安全映射

Javascript Typescript-键到类型和值的类型安全映射,javascript,typescript,typescript-generics,Javascript,Typescript,Typescript Generics,我的目标是创建一个函数,该函数接受一个键和一个带有查询参数的对象,该函数可以查找URL,使用查询参数进行插值并导航到该URL。到目前为止我得到的是这个 interface FooIdParams { fooId: number; } interface QueryParams<P = never> { params: P; } enum Urls { 'foo-editor' = '/editfoo?fooId=${fooId}'

我的目标是创建一个函数,该函数接受一个键和一个带有查询参数的对象,该函数可以查找URL,使用查询参数进行插值并导航到该URL。到目前为止我得到的是这个

  interface FooIdParams {
    fooId: number;
  }

  interface QueryParams<P = never> {
    params: P;
  }

  enum Urls {
    'foo-editor' = '/editfoo?fooId=${fooId}'
  }

  interface ParamTypes {
    'foo-editor': QueryParams<FooIdParams>
  }
接口foodParams{
fooId:数字;
}
接口查询参数{
参数:P;
}
枚举URL{
'foo editor'='/editfoo?fooId=${fooId}'
}
接口参数类型{
“foo编辑器”:查询参数
}
我的类中的load方法如下所示:

  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
  }
load=(目标:T,参数:ParamTypes[T][“params”]):void=>{
常量url=eval('`+url[target]+'`'))
//注释中建议的替换为类似的替换
//这也适用于多个查询参数
常量url2=URL[target].replaceAll(/\$\{(.*?\}/g,([uuU2:string,k:string)=>(参数如有)[k])
//还有一些代码来打开那个页面
}
这已经起作用,并确保被调用的提供了正确的查询参数(稍后我有几十个URL目标,并且从许多地方调用了load方法,因此值得付出努力)

我无法解决的部分:我在两个不同的位置使用键
foo编辑器
,一个是映射到“url”的枚举,另一个是映射到类型的接口。我想保证,enum和interface都有完全相同的键(like-typescript应该在两者中强制映射并防止输入错误)


有没有办法确保?

您可以用映射类型替换枚举:

 const Urls: { [K in keyof ParamTypes]: string } = {
   /*...*/
 };

我将使用
.replace(/\$\{(.*)}/g,k=>params[k]),而不是
eval
我尝试过-但这不是那么容易,因为我现在必须找到
k
-typescript的正确类型。可能其中一种情况是
any
简化了事情()是的,这里可以接受-我已经在方法上有了类型安全性,因此,
params
保证为正确类型,并具有所有必需的密钥。谢谢@Jonaswillms-我已经转向您的建议,但您的解决方案有两个错误:第一,代码中的
k
是完全匹配的-第二个是我们想要的捕获值。然后,它只使用一个参数,因为默认情况下regexp是贪婪的。我编辑了我的问题,并将可行的备选方案放入其中。谢谢你至少为我指明了方向!小改进:非常感谢!钥匙中的
是我丢失的那块。它现在就像一个符咒一样工作。@据我所知,每个请求的ParamType都不同,因此该类型必须是定义键的类型。@Jonaswillms我的重点主要是使用不可变对象而不是枚举。我没有深入研究question@captain-yossarian-我看到了这个添加,并将
添加为const
到我的真实代码中。非常宝贵!谢谢,我不知道这是可能的