Typescript在访问映射的Proxy对象时丢失了键类型的特定性



TL;DR我可以防止key扩展到string吗?

type Foo = {
[key in string]: key
}
type Test = Foo['bar']
//   ^? type Test = string

如何使Test的类型为'bar'而不是string


我正在尝试键入用于访问API的Proxy。这个API有一些预先知道的端点,也有一些不知道的端点。出于这个原因,我需要代理来处理已知字符串('a' | 'b' | 'c')和未知字符串(string)。

我以一个";模式";已知终点的

type Paths = {
'/a/b/{id}': {}
'foo/bar': {}
}

我有这种类型,可以推断出";动态部件";URL的

type ExtractParams<url extends string> = 
url extends `${string}{${infer A extends string}}${string}`
? {[param in A]: string}
: {}
type test = ExtractParams<'/a/b/{foo}'>
//   ^? type test = { foo: string }

当尝试键入Proxy时;已知的";以及";未知";端点,所以我正在做这样的事情:

type MyProxy = {
[key in keyof Paths]: ExtractParams<key>
} & {
[key in string]: ExtractParams<key>
}

允许访问任何字符串

MyProxy['/a/b/{id}'] // known from `Paths`, no issue
MyProxy['/la/la/la'] // unknown from `Paths`, no issue

但问题是打字脚本无法正确地";推断动态部分";未知端点,因为它只是将它们键入为string:

type knownPathParam = MyProxy['/a/b/{id}']
//   ^? type knownPathParam = { id: string } <-- correct, because `/a/b/{id}` is in Paths
type unknownPathParam = MyProxy['/d/e/{id}']
//   ^? type unknownPathParam = {}           <-- incorrect, we would want `{ id: string }`

正如我们在上面看到的,无论我们传递哪个字符串,ExtractParams都能工作,问题来自于这样一个事实,即来自key in string的任何密钥都会归结为string,而不是"1";"保持其价值":

type BasicDemo = {
[key in string]: key
}
type test = BasicDemo['some specific string']
//   ^? type test = string

CCD_ 14是否有办法保留";特定字符串";在这里访问

链接到这个演示的打字游戏场

tl;dr:没有泛型就无法做到这一点,这里有一个带有泛型的解决方案:

type MyProxy<T extends string> = T extends keyof paths ?
ExtractParams<T> : // modify this
ExtractParams<T>
type knownPathParam = MyProxy<'/a/b/{id}'>
//   ^? type knownPathParam = { id: string }
type unknownPathParam = MyProxy<'/d/e/{id}'>
//   ^? type unknownPathParam = { id: string }

我想你可能想修改已知路径的行为,所以我把MyProxy留作有条件的。


NO的原因是[key in string]: ExtractParams<key>不是泛型,因此ExtractParams<key>将立即进行推理,使用string作为推理的类型参数

最新更新