使用 returns 与其参数类型相同的可区分联合来声明 TypeScript 函数的最佳方法是什么?
What's the best way to declare a TypeScript function with a discriminated union that returns the same type as its parameter?
给定这个简化的 vanilla JS 函数:
function getStringOrNumber(val) {
if (typeof val === 'string') {
return 'It was a string';
} else {
return 5;
}
}
我如何告诉 TypeScript 当它得到一个字符串时它 returns 一个字符串,当它得到一个数字时它 returns 一个数字?
我尝试了不同的方法,发现使用这些重载是有效的,但它似乎过于复杂,我想知道我是否遗漏了什么。特别是,在此解决方案中,我不明白为什么需要第三行(有关详细信息,请参阅下面的 link)。
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;
}
}
您的重载解决方案已经完成。问题出在你的测试上。在您的测试中,您正在调用将联合作为参数传递的方法,但联合不是允许的值:只有 string
和 number
是。最后重载("implementation overload")is not part of the signature。所以你的测试必须执行缩小,像这样:
function getValOverloads(val: string | number): string | number {
if (typeof val === 'string')
return useOverloads(val);
else
return useOverloads(val);
}
如果您希望能够传递联合(并因此接收联合作为 return 值),您应该添加第三个重载(就像您在 useOverloadsExtra
上所做的那样)。
给定这个简化的 vanilla JS 函数:
function getStringOrNumber(val) {
if (typeof val === 'string') {
return 'It was a string';
} else {
return 5;
}
}
我如何告诉 TypeScript 当它得到一个字符串时它 returns 一个字符串,当它得到一个数字时它 returns 一个数字?
我尝试了不同的方法,发现使用这些重载是有效的,但它似乎过于复杂,我想知道我是否遗漏了什么。特别是,在此解决方案中,我不明白为什么需要第三行(有关详细信息,请参阅下面的 link)。
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;
}
}
您的重载解决方案已经完成。问题出在你的测试上。在您的测试中,您正在调用将联合作为参数传递的方法,但联合不是允许的值:只有 string
和 number
是。最后重载("implementation overload")is not part of the signature。所以你的测试必须执行缩小,像这样:
function getValOverloads(val: string | number): string | number {
if (typeof val === 'string')
return useOverloads(val);
else
return useOverloads(val);
}
如果您希望能够传递联合(并因此接收联合作为 return 值),您应该添加第三个重载(就像您在 useOverloadsExtra
上所做的那样)。