【发布时间】:2022-01-17 11:20:00
【问题描述】:
This example code 有点做作,但我正在尝试做类似的事情:
type ValueRequirement =
| 'None'
| 'Any String'
| 'Any Number'
| 'Another Widget\'s Value';
type Widget = {
value: string
}
type WidgetValidationRule = {
widget: Widget,
valueRequirement: ValueRequirement,
}
function isANumber(value: string): boolean {
throw new Error("Function not implemented."); // irrelevant implementation. Just trying to provide an example that can compile
}
function validate(widgetValidationRule: WidgetValidationRule): void {
switch (widgetValidationRule.valueRequirement) {
case 'None':
return
case 'Any Number':
if (!isANumber(widgetValidationRule.widget.value)) {
throw new Error('NaN');
}
return
// ...
}
}
我一直在慢慢地向ValueRequirement 添加更多值,我刚刚添加了一个新值'Another Widget\'s Value'。为此,我意识到我实际上无法检查这是否有效,除非 validate 传递了所有其他存在的 Widgets 的列表。
一方面,当且仅当ValueRequirement 为'Another Widget\'s Value' 时,我可以将allWidgets: Widget[] 添加为可选参数并在未定义的情况下抛出运行时异常。
我宁愿有一个编译时错误:如果ValueRequirement 是'Another Widget\'s Value',那么所有其他Widgets 的列表必须作为附加参数传入。否则传不进去。I imagine the solution would look something like this,但是我想不出办法让它编译:
type ValueRequirement =
| 'None'
| 'Any String'
| 'Any Number'
| 'Another Widget\'s Value';
type Widget = {
value: string
}
type WidgetValidationRule = {
widget: Widget,
valueRequirement: ValueRequirement,
}
function isANumber(value: string): boolean {
throw new Error("Function not implemented.");
}
function validate({widget, valueRequirement: 'Another Widget\'s Value'}: WidgetValidationRule, allWidgets: Widget[]): void;
function validate({widget, valueRequirement: 'None' | 'Any String' | 'Any Number'}: WidgetValidationRule): void;
function validate(widgetValidationRule: WidgetValidationRule, allWidgets?: Widget[]): void {
//impl
}
一般来说有很多关于重载的类似问题,但在这种情况下,我必须解构一个类型并知道要重载的 ValueRequirement 值。
我一直在阅读有关如何使用 destructure objects 和 function overloading 的手册,但他们没有提到这种用例。我不确定这是否意味着不可能,我正在阅读文档的错误部分,或者这是一个很少有人问过的非常不寻常的问题(我在写这篇文章之前尝试了谷歌搜索)。
Destructuring with function overloading 的标题看起来很相似,但它是关于实现内部的解构。我说的是解构函数签名本身。
在 typescript 中,可以根据解构参数重载函数吗?
我想我要将ValueRequirement 从WidgetValidationRule 移动到validate 函数作为参数。那么这似乎很简单。无论如何,我很好奇这个问题的答案。
【问题讨论】:
-
this approach 是否满足您的需求?我不确定您是否真的关心重载或破坏,因为您的示例代码都没有显示。我试图给出一个“解构调用签名”,但没有实际的重载。或者你可以重载但你不需要解构。在这两种情况下,实现都无法理解
ValueRequirement属性与另一个函数参数的存在/不存在之间的相关性...... -
...如果您真的需要在调用和实现方面都有效的东西,那么您需要像 this 这样的有区别的联合。如果你想让我写下这些作为答案,请告诉我。如果我遗漏了什么,请edit 提供一个真实的minimal reproducible example 来证明你的目标。
-
@jcalz 感谢您的帮助,但 jsejcksn 的答案正是我想要的。
-
那么答案中的解构在哪里?我在这里错过了什么?
-
@jcalz 公平点。它不在那里。我认为解决我的问题需要解构。显然它没有。我在上面写了一些非编译代码来说明我认为我需要的解决方案类型。
标签: typescript types