我有一个名为"onHook
"的静态函数。这个函数有两个参数,一个ID
和一个Callback
。我的目标是根据Hook ID的类型更改回调参数的类型。
现在我设法让这个工作:
打字操场
enum HookID {
OnOpened,
OnClosed,
}
type HookArguments<T> =
T extends HookID.OnOpened ? {
arg1: string,
arg2: string
}:
T extends HookID.OnClosed ? {
arg3: boolean,
arg4: boolean
} : never;
function onHook<T>(id: HookID, callback: (arg: HookArguments<T>)=> void){
// **** //
}
onHook<HookID.OnClosed>(HookID.OnClosed, (args)=>{
/** args.arg3 and args.arg4 are availables */
})
但是必须同时在泛型类型和ID参数中声明枚举似乎不是最优的。有没有办法获取ID参数的类型并将其注入Argument泛型类型?
大概是这样的
function onHook(id: HookID, callback: (arg: HookArguments<this.id>)=> void){
// **** //
}
onHook(HookID.OnClosed, (args)=>{
// **** //
})
2条答案
按热度按时间ds97pgxw1#
你的意图是
id
参数和你用来确定callback
参数的generic类型是一样的,对吗?当你调用它的时候,编译器现在可以从
id
参数中 * 推断 *T
,所以args
会自动得到你想要的类型:这就是问题的答案,但是顺便说一句,您不需要使用conditional types来定义
HookArguments
,因为您希望将数字枚举Map到任意类型,所以可以使用对象类型来捕获它,因为对象类型擅长描述从类似于键的类型的Map(string
、number
或symbol
,枚举是字符串/数字)转换为其他类型,然后只需使用枚举对对象类型执行index into操作即可查找相关属性:这对于您的目的来说是相同的,但是是一个更传统的实现。
Playground代码链接
von4xj4u2#
使用
onHook<T extends HookID>()
而不是<T>
的泛型,然后将第一个参数设置为类型T
,这仍然需要它是HookID。