在泛型函数中按名称调用方法
Call method by name inside generic function
我想概括这里描述的情况:
所以我将有一个类似于下面的函数 (genericFunction),其中我还不知道 obj
类型,但我想确保obj[key]
只能是特定类型。
///
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
。我们可以翻转它,让它依赖于密钥的类型。
我们使用一个辅助实用程序类型来定义一个对象,该对象的所有可分配给 Key
的键都有一个可分配给 Value
.
的值
export type HasProperty<Key extends keyof any, Value> = {
[K in Key]: Value;
}
现在我们让 genericFunction
依赖于一个键 K extends keyof any
。 methodName
是 K
类型,对象是一个对象,每个 K
键都有一个无参数 void
函数。
function genericFunction<K extends keyof any>(
obj: HasProperty<K, () => void>,
methodName: K
): void {
const method = obj[methodName];
method();
}
这按预期工作,如果对象类型没有 methodName
中的 属性 函数,则会给我们一个错误。
genericFunction({} as IType, 'f'); // ok
genericFunction({} as IType, 'm'); // ok
genericFunction({} as IType, 'p'); // error
我想概括这里描述的情况:
所以我将有一个类似于下面的函数 (genericFunction),其中我还不知道 obj
类型,但我想确保obj[key]
只能是特定类型。
///
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
。我们可以翻转它,让它依赖于密钥的类型。
我们使用一个辅助实用程序类型来定义一个对象,该对象的所有可分配给 Key
的键都有一个可分配给 Value
.
export type HasProperty<Key extends keyof any, Value> = {
[K in Key]: Value;
}
现在我们让 genericFunction
依赖于一个键 K extends keyof any
。 methodName
是 K
类型,对象是一个对象,每个 K
键都有一个无参数 void
函数。
function genericFunction<K extends keyof any>(
obj: HasProperty<K, () => void>,
methodName: K
): void {
const method = obj[methodName];
method();
}
这按预期工作,如果对象类型没有 methodName
中的 属性 函数,则会给我们一个错误。
genericFunction({} as IType, 'f'); // ok
genericFunction({} as IType, 'm'); // ok
genericFunction({} as IType, 'p'); // error