我正在尝试为特定用例创建一个React高阶组件,问题可归结为以下内容:
function sample<TObj, P extends keyof TObj, F extends keyof TObj>(
obj: TObj,
prop: P,
setProp: TObj[F] extends (value: TObj[P]) => void ? F : never
) {
obj[setProp](obj[prop]);
}
我希望能够传递一个对象,一个字符串,该字符串应该是该对象的键,以及该对象的另一个键,但必须是一个函数。
可以这样进一步简化:
function sample2<TObj, F extends keyof TObj>(
obj: TObj,
setProp: TObj[F] extends () => void ? F : never
) {
obj[setProp]();
}
在我看来,因为我使用了条件类型,因此可以保证obj[setProp]
将是一个函数,但出现错误:
This expression is not callable.
Type 'unknown' has no call signatures.ts(2349)
如下所示,如果使用不符合要求的键调用该函数,则会出错。但是似乎没有在函数内部应用相同的要求。
我知道这可以看作是XY问题,但它使我对是否有一种方法可以使此特定问题正常工作感到非常感兴趣。
在sample()
的实现中,类型TObj[F] extends () => void ? F : never
是未解析的条件类型。也就是说,它是一个条件类型,它取决于要解析的当前未指定的泛型类型参数。在这种情况下,编译器通常不知道如何处理并将其本质上视为不透明的。 (有关此问题的讨论,请参见microsoft/TypeScript#23132。)尤其是,它没有意识到TObj[Tobj[F] extends ()=>void ? F : never]
最终将不得不解析为()=>void
的某些子类型。