使用条件类型功能,我们可以实现一个函数,该函数的返回类型取决于其参数的值:
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
上,而不是将它们分别简化为number
或boolean
(我们必须添加使编译器满意的强制转换。)
这两个问题似乎与以下事实有关:编译器并未完全推断出诸如A extends "a" | "b"
之类的类型,编译器无法在case语句中找到穷举性或对其进行细化。
所以我的问题是:是否可以采用这种方法,或者是否有更好的方法来实现具有相关返回类型的函数,这样我们就不必依靠不需要的throw
进行强制转换了?
答案 0 :(得分:0)
尽管您的方法不一定很糟糕,但可能需要对功能使用两个签名来进行改进。使用条件类型指定参数和返回类型之间关系的公共通用签名,以及非通用实现签名,这将使编译器更易于理解:
FormName.ActiveForm.Hide();
这不会强制您尊重输入和输出参数之间的关系,但是原始参数也不会。至少此版本避免在实现中使用类型断言。