首页 > 解决方案 > 在 Typescript 中按名称从字典中调用函数

问题描述

假设我有一个具有多个功能的接口:

// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0

interface MyFunctions {
  func1: () => string;
  func2: () => number;
  func3: (value: string) => string;
}

现在我想按名称获取这些函数:

// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0

type FuncNames = keyof MyFunctions;

function getFunc<T extends FuncNames>(key: T): MyFunctions[T] {
  return myFuncInstance[key]; // Imagine I have instance coming from somewhere.
}

这实际上完全是类型安全的:

// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0

const a = getFunc('func1')(); // a - string;
const b = getFunc('func2')(); // b - number;
const c = getFunc('func3')('some'); // c - string;

现在我想再做一步并在助手中调用函数:

// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0

function callFunc<T extends FuncNames>(
    key: T, 
    ...params: Parameters<MyFunctions[T]>): ReturnType<MyFunctions[T]> {
  const func = getFunc(key);
  return func(...params);  // Type error here.
}

所以我希望这个工作,但不能存档。TypeScript 可以吗?

// Copyright 2020 Google LLC.
// SPDX-License-Identifier: Apache-2.0

const a = callFunc('func1'); // a - string;
const b = callFunc('func2'); // b - number;
const c = callFunc('func3', 'some'); // c - string;

顺便说一句,签名的callFunc检查正确。因此编译器成功地检查了上一个示例中的调用,并强制参数callFunc正确,但我无法在此帮助程序中进行实际调用。因此,如果我做的事情就像const func: any = getFunc(key);外面的一切仍然是类型安全的,但any总是使用是一个不好的迹象。

是否可以使callFunc完全类型安全?

标签: typescripttypescript-typingstypescript-generics

解决方案


推荐阅读