泛型函数中按名称调用方法 [英] Call method by name inside generic function

查看:95
本文介绍了泛型函数中按名称调用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关问题

部分解决方案

我想概括一下这里描述的情况:根据返回类型限制'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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆