给出重载函数语句的以下实现:
function foo(options: "a"): "a";
function foo(options: "b"): "b";
function foo(options: "a" | "b"): "a" | "b" {
switch (options) {
case "a":
return `a`;
case "b":
default:
return `b`;
}
}
我可以这样调用该函数:
// this works
const url1 = foo("a");
const url2 = foo("b");
但是,如果我调用foo
使用联合类型的值调用时的函数"a" | "b"
:
// function call (inside of wrapped function)
type Options = "a" | "b";
const wrapper = (options: Options) => {
// function overloading forces the caller to narrow the type
const url = foo(options); // Error: Type '"a"' is not assignable to type '"b"'.
}
我可以通过解决这个问题
function foo(options: "a"): "a";
function foo(options: "b"): "b";
function foo(options: "a" | "b"): "a" | "b" {
switch (options) {
case "a":
return "a";
case "b":
default:
return "b";
}
}
type Options = "a" | "b";
const wrapper = (options: Options) => {
// Solution: Calling function 'foo' in the exact same way
const url = options === "a" ? foo(options) : foo(options);
}
Question:为什么 TypeScript 强迫我缩小范围options
值,因为它对我的调用方式没有影响foo
?
我总是打电话foo
as foo(options)
。如果重载的类型签名差异较大,例如,如果某些重载包含可选参数值,TS 当然应该提示我缩小类型。但难道不应该推断在这样的场景中没有必要吗?
我的问题的 TypeScript Playground
function foo(options: "a"): "a";
function foo(options: "b"): "b";
function foo(options: "a" | "b"): "a" | "b" {
最后一行是函数实现的开始,但它不是外部世界可见的类型的一部分。所以用你写的代码,传递一些类型"a" | "b"
实际上是不允许的。只是"a"
or "b"
他们自己。
错误消息可能包含以下文本,它试图指出问题,但如果您以前从未见过它,可能很难理解它的含义:
针对此实现的调用将成功,但重载的实现签名在外部不可见。
解决方法是在定义中再添加一个重载:
function foo(options: "a"): "a";
function foo(options: "b"): "b";
function foo(options: "a" | "b"): "a" | "b";
function foo(options: "a" | "b"): "a" | "b" {
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)