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
作为推理的类型参数