[英]What's the best way to declare a TypeScript function with a discriminated union that returns the same type as its parameter?
Given this simplified vanilla JS function:鉴于这个简化的 vanilla JS 函数:
function getStringOrNumber(val) {
if (typeof val === 'string') {
return 'It was a string';
} else {
return 5;
}
}
How can I tell TypeScript that when it gets a string it returns a string, and when it gets a number it returns a number?我怎么能告诉 TypeScript 当它得到一个字符串时它返回一个字符串,当它得到一个数字时它返回一个数字?
I have experimented with different methods and found that using these overloads works, but it seems over-complicated and I wonder if there's something I am missing.我尝试了不同的方法,发现使用这些重载是有效的,但它似乎过于复杂,我想知道我是否遗漏了什么。 Particularly, in this solution, I don't get why the third line is necessary (see link below for more info).
特别是,在这个解决方案中,我不明白为什么需要第三行(有关更多信息,请参见下面的链接)。
function useOverloadsExtra(val: string): string
function useOverloadsExtra(val: number): number
function useOverloadsExtra(val: string | number): string | number
function useOverloadsExtra(val: string | number): string | number {
if (typeof val === 'string') {
return 'It was a string';
} else {
return 5;
}
}
Your overloads solution is close.您的重载解决方案很接近。 The problem is on your test.
问题出在你的测试上。 In your test, you are calling the method passing the union as the parameter, but the union is not an allowed value: only
string
and number
are.在您的测试中,您正在调用传递联合作为参数的方法,但联合不是允许的值:只有
string
和number
。 The last overload (the "implementation overload") is not part of the signature .最后一个重载(“实现重载”) 不是签名的一部分。 So your test must perform the narrowing, like this:
因此,您的测试必须执行缩小,如下所示:
function getValOverloads(val: string | number): string | number {
if (typeof val === 'string')
return useOverloads(val);
else
return useOverloads(val);
}
If you want to be able to pass the union (and thus receiving the union as the return value), you should add a third overload (just like you did on useOverloadsExtra
).如果您希望能够传递联合(从而接收联合作为返回值),您应该添加第三个重载(就像您在
useOverloadsExtra
上useOverloadsExtra
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.