網站搜尋

javascript - 在 typescript 中將變數用作方法


我想在 TypeScript 中通過變量名稱動態地調用方法,如以下示例所示。

function callMethod(_class, method: string){
  let classObj = new _class();
  return classObj[method]()
}

先前的程式碼片段沒有真正的好處,但它顯然可以用最少的程式碼解釋這個想法。

不過,如果你在 tsconfig.json 中啟用了選項 noImplicitAny,你就必須添加類型註解

return classObj[method as keyof typeof classObj]()

理論上,它在 Js 中運作良好,但 ts 抱怨不是所有組成部分都是可呼叫的,並顯示此錯誤:

This expression is not callable.
  Not all constituents of type ... are callable.

我如何在 TypeScript 中動態調用一個方法?

答案#1

如果你把方法、類別以及類別的靜態部分都設為泛型,你可以這樣做:

function callMethod<
  M extends PropertyKey,
  C extends {[K in M]: () => any},
  T extends {new(): C}
>(_class: T, method: M): ReturnType<InstanceType<T>[M]> {
  const classObj = new _class();

  return classObj[method]() 
}

class Test {
    someMethod(): number { return 8}
}

const t1 = callMethod(Test, 'someMethod') // Inferred type: number.

const t2: string = callMethod(Test, 'someMethod')
// ERROR: .. Type 'number' is not assignable to type 'string'.

const t3 = callMethod(Test, 'noMethod')
// ERROR: .. Property 'noMethod' is missing in type 'Test' but required in
//        type '{ noMethod: () => unknown; }'.

TypeScript 遊樂場

在 callMethod 內,method 的返回類型將是 any,但將其類型化為第四個類型參數並使其與 ReturnType<InstanceType<T>[M]> 相符似乎很棘手(並且可能不可能)。不過,只要你直接返回方法調用的結果,這應該不會造成太大的問題。