我正在实现一个接收对象和属性名称的 call
函数,然后在传递的属性中调用驻留在传递对象中的函数 .
function call<
T,
K extends {
[K in keyof T]: T[K] extends Function ? K : never
}[keyof T],
>(t: T, func: K) {
t[func]();
}
看起来ts很满意并正确过滤属性(没有 prop
,只有 do
可用):
但它也在我调用函数的行上显示错误: t[func]();
:
Cannot invoke an expression whose type lacks a call signature.
Type '{}' has no compatible call signatures.
我找到了类似的issue [Type deduction using mapped types and generics]但它被关闭为另一个issue [Call signatures of union types]的副本 . 显然问题是第二个泛型参数实际上是满足条件的所有属性名称的联合类型 .
有没有其他方法可以解决这个问题,除了转换为 any
?
PS:Playground
1 回答
打字稿将无法确定您对属性的过滤意味着
T[K]
始终是一个函数 . 您可以稍微反转约束,以指定T
扩展具有()=>void
类型属性的内容但请注意,您可以考虑在原始函数中使用断言,上面的版本同时避免断言并且类型安全无助于知识分子找出可以为第二个参数分配哪些可能的值,因此不是这样:
你明白这个:
虽然在这种情况下通常应该避免断言,但我们确信该类型实际上是正确的,因为我们对key有约束,所以这个版本也应该没问题: