如果属性成员是函数类型,如何在Typescript中动态调用

如果属性成员是函数类型,如何在Typescript中动态调用,typescript,typescript-typings,typescript-generics,Typescript,Typescript Typings,Typescript Generics,如果成员是函数,我想调用。如何在typesript中执行此操作。 typescript不鼓励动态键入吗? function call_IF_Fucntion<T, K extends keyof T>(obj: T, propName: K) { if (typeof obj[propName] === "function") { obj[propName](); //// This expression is not c

如果成员是函数,我想调用。如何在typesript中执行此操作。

typescript不鼓励动态键入吗?

function call_IF_Fucntion<T, K extends keyof T>(obj: T, propName: K) {

  if (typeof obj[propName] === "function") {
     
      obj[propName]();

     //// This expression is not callable, Type unknown ha no call signature
     
  }

}


let x = {
  name: "manas",
  age: 30,
  run: () => {
    console.log("running ... ");
  }
};

call_IF_Fucntion(x, "run");

函数调用IF函数(obj:T,propName:K){ if(对象类型[propName]=“功能”){ obj[propName](); ////此表达式不可调用,类型未知,没有调用签名 } } 设x={ 名称:“玛纳斯”, 年龄:30,, 运行:()=>{ 日志(“正在运行…”); } }; 调用函数(x,“运行”);
这里发生的主要事情是,如果使用括号表示法(如
obj[propName]
)而不是使用点表示法(如
obj.xyz
)执行索引,则TypeScript不用于缩小属性的类型。这被认为是TypeScript中的一个bug;请参阅,它还没有被修复,因为修复程序太慢了编译器,而且还不清楚如何在所有情况下安全地执行此操作(有关更多信息,请参阅相关问题)

这里通常使用的解决方法是将属性保存到自己的变量中,然后使用控制流分析缩小该变量的范围:

function call_IF_Fucntion<T, K extends keyof T>(obj: T, propName: K) {
  const objPropName = obj[propName];
  if (typeof objPropName === "function") {
    // const objPropName: T[K] & Function
    objPropName(); // okay
  }
}
如果要防止出现这种情况,应该
T
,这样它的函数值属性就不需要任何参数了。。。也许是这样:

function call_IF_Function<
  T extends Record<K, (() => void) | string | number>,
  K extends keyof T
>(obj: T, propName: K) {
  const objPropName = obj[propName];
  if (typeof objPropName === "function") {
    // const objPropName: T[K] & Function
    objPropName();
  }
}

感谢您给我时间并写下详细的答案。高度赞赏
function call_IF_Function<
  T extends Record<K, (() => void) | string | number>,
  K extends keyof T
>(obj: T, propName: K) {
  const objPropName = obj[propName];
  if (typeof objPropName === "function") {
    // const objPropName: T[K] & Function
    objPropName();
  }
}
call_IF_Function(x, "name"); // okay

call_IF_Function({ oops: (s: string) => s.toUpperCase() }, "oops"); // error!
// --------------------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type '(s: string) => string' is not assignable to type '() => void'