【发布时间】:2022-01-05 02:01:33
【问题描述】:
给定以下类型
type Tool = 'network_query' | 'cluster'
type Network = 'one' | 'two' | 'three'
class QueryOneParams {...}
class QueryTwoParams {...}
class QueryThreeParams {...}
class ClusterParams {...}
我正在尝试定义Tool 和Network 组合之间的映射,以便我可以编写如下内容:
const queryParamsLookup = {
'one': QueryOneParams,
'two': QueryTwoParams,
'three': QueryThreeParams
}
type Job<Tool, Network> = {
id: string,
params: JobParams<Tool, Network>
}
在哪里
-
JobParams<'network_query', 'one'>解析为QueryOneParams -
JobParams<'network_query', 'two'>解析为QueryTwoParams -
JobParams<'network_query', 'three'>解析为QueryThreeParams -
JobParams<'cluster'>解析为ClusterParams -
JobParams<'cluster', 'one'>、JobParams<'cluster', 'two'>和JobParams<'cluster', 'three'>无效
这需要我以某种方式定义第二个泛型参数'one' | 'two' | 'three' 仅在第一个参数是'network_query' 时才使用和必需。 Afaik,Typescript 不支持基于另一个参数的类型可选定义的泛型参数。
正确吗?我很想在这里犯错:)
作为替代方案,我定义了一个辅助类型,如下所示:
type NetworkQueryJobType = {
[N in keyof typeof queryParamsLookup]: ['network_query', N]
}[keyof typeof queryParamsLookup]
// ['network_query', 'one'] | ['network_query', 'two'] | ['network_query', 'three']
type JobType = NetworkQueryJobType | ['cluster']
// ['network_query', 'one'] | ['network_query', 'two'] | ['network_query', 'three'] | ['cluster']
并将Job的定义改为
type Job<JobType> = {
id: string,
params: JobParams<JobType>
}
使用这种方法,我无法让类型推断在映射器类型JobParams 中正常工作:
type JobParams<T extends JobType> = T extends ['network_query', infer N] ?
typeof queryParamsLookup[N] // Error: N is not compatible with 'one' | 'two' | 'three'
: ClusterParams
我可以解决类型推断问题:
type JobParams<T extends JobType> = T extends ['network_query', infer N] ?
N extends Network ?
typeof queryParamsLookup[N] // No error
: ClusterParams
: ClusterParams
然而,所有这些仍然让我在键入时自动完成性能不佳,例如:
const params: JobParams<['
VSCode 不会建议'cluster' | 'network_query'
总而言之,我觉得在这里打一场失败的战斗。我做错了什么?
【问题讨论】:
-
你不是在
queryParamsLookup中使用QueryOneParams作为表达式吗? -
是的,你完全正确!我的意图是抽象出我的一些实现细节。实际上,
QueryOneParams和朋友是班级。我会在问题中更改它。谢谢你抓住这个:) -
我已经为你添加了一个游乐场链接(太长了,无法放入评论)。您的
Job类型出错。请修复它并更新问题中的链接。
标签: typescript typescript-typings typescript-generics