有没有更好的方法来实现具有依赖返回类型的函数?

时间:2018-09-30 08:21:22

标签: typescript

使用条件类型功能,我们可以实现一个函数,该函数的返回类型取决于其参数的值:

function func<A extends "a" | "b">(
  a: A,
): A extends "a" ? number : A extends "b" ? boolean : never {
  switch (a) {
    case "a": {
      return <any>1;
    }
    case "b": {
      return <any>true;
    }
  }
  throw "impossible";
}

// using the function
// x is inferred `number`
const x = func("a");

// y is inferred `boolean`
const y = func("b");

函数func"a""b"作为输入,如果接收到前者,则返回number,如果接收到前者,则返回boolean后者。

但是,由于使用A extends "a" | "b",我们不得不两次协助编译器:编译器无法检测到案件已得到彻底处理(我们必须在结尾处添加throw函数),并且编译器不会在case表达式中简化所需的返回类型,而将其保留在A extends "a" ? number : A extends "b" ? boolean : never上,而不是将它们分别简化为numberboolean(我们必须添加使编译器满意的强制转换。)

这两个问题似乎与以下事实有关:编译器并未完全推断出诸如A extends "a" | "b"之类的类型,编译器无法在case语句中找到穷举性或对其进行细化。

所以我的问题是:是否可以采用这种方法,或者是否有更好的方法来实现具有相关返回类型的函数,这样我们就不必依靠不需要的throw进行强制转换了?

1 个答案:

答案 0 :(得分:0)

尽管您的方法不一定很糟糕,但可能需要对功能使用两个签名来进行改进。使用条件类型指定参数和返回类型之间关系的公共通用签名,以及非通用实现签名,这将使编译器更易于理解:

FormName.ActiveForm.Hide();

这不会强制您尊重输入和输出参数之间的关系,但是原始参数也不会。至少此版本避免在实现中使用类型断言。