泛型函数中按名称调用方法 [英] Call method by name inside generic function
问题描述
我想概括一下这里描述的情况:根据返回类型限制'Type'的键
I want to generalize the situation described here: Restrict keyof 'Type' according to return type
所以我将拥有一个类似于下面的函数( genericFunction ),其中我还不知道obj
类型,但是我想确保obj[key]
只能是特定类型的
So I will have a function like the one below (genericFunction) where I don't know the obj
type yet, but I want to make sure that the obj[key]
can only be of a specific type.
/// https://stackoverflow.com/a/58880555/4233401
type Identical<T, TTest, TTrue, TFalse> = (<U extends T>(
o: U
) => void) extends <U extends TTest>(o: U) => void
? TTrue
: TFalse;
type KeyWithValueOfType<THost, TValueType> = {
[K in keyof THost]: Identical<THost[K], TValueType, K, never>;
// [K in keyof THost]: THost[K] extends TValueType ? K : never;
}[keyof THost];
function genericFunction<T>(
obj: T,
methodName: KeyWithValueOfType<T, () => void>
): void {
const method = obj[methodName];
// How can I guarantee that method is callable?
// Or that it is the type that I restricted at KeyWithValueOfType <THost, TValueType>
method(); // This expression is not callable.
// Type 'unknown' has no call signatures.
}
type TTypeMethod = KeyWithValueOfType<IType, () => void>; // = "function" | "method"
genericFunction({} as IType, 'f'); // ok
genericFunction({} as IType, 'm'); // ok
genericFunction({} as IType, 'p'); // ok
推荐答案
现在,您的genericFunction
取决于对象T
的类型.我们可以将其翻转,然后使其依赖于键的类型.
Right now your genericFunction
is dependent on the type of the object T
. We can flip it around and make it dependent on the type of the key instead.
我们使用帮助程序实用程序类型来定义一个对象,对于该对象,所有可分配给Key
的键都具有可分配给Value
的值.
We use a helper utility type that defines an object for which all keys assignable to Key
have a value that is assignable to Value
.
export type HasProperty<Key extends keyof any, Value> = {
[K in Key]: Value;
}
现在,使我们的genericFunction
依赖于键K extends keyof any
. methodName
的类型为K
,并且该对象是每个K
键都具有无参数void
函数的对象.
Now we make our genericFunction
dependent on a key K extends keyof any
. The methodName
is of type K
and the object is an object which has a parameterless void
function for every K
key.
function genericFunction<K extends keyof any>(
obj: HasProperty<K, () => void>,
methodName: K
): void {
const method = obj[methodName];
method();
}
这可以按预期工作,如果对象类型没有methodName
中的属性功能,则会给我们一个错误.
This works as expected, giving us an error if the object type doesn't have a function as the property in methodName
.
genericFunction({} as IType, 'f'); // ok
genericFunction({} as IType, 'm'); // ok
genericFunction({} as IType, 'p'); // error
这篇关于泛型函数中按名称调用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!