Typescript 什么';标记的联合体的通用匹配函数的正确类型是什么?
我想实现一个Typescript 什么';标记的联合体的通用匹配函数的正确类型是什么?,typescript,Typescript,我想实现一个match函数,该函数的工作原理类似于Rust,但针对TypeScript的结构类型系统进行了调整 可以(但不符合人体工程学)为每个需要匹配的未命名标记的联合显式编写功能类型。目前最好的替代方案似乎是switch case,它必须包装在(()=>{})(中才能作为表达式使用 //此函数应具有什么类型? 功能匹配(值、案例){ 返回案例[value.tag](值); } //例1 字体形状= |{标记:'圆',半径:数字} |{tag:'textbox',text:string}; c
match
函数,该函数的工作原理类似于Rust,但针对TypeScript的结构类型系统进行了调整
可以(但不符合人体工程学)为每个需要匹配的未命名标记的联合显式编写功能类型。目前最好的替代方案似乎是switch case,它必须包装在(()=>{})(
中才能作为表达式使用
//此函数应具有什么类型?
功能匹配(值、案例){
返回案例[value.tag](值);
}
//例1
字体形状=
|{标记:'圆',半径:数字}
|{tag:'textbox',text:string};
constshape:shape={tag:'textbox',text:'helloworld!';
原木(匹配)形状{
//这两个字段都是必需的
圆:({radius})=>`半径为${radius}`的圆,
textbox:({text})=>`显示“${text}”的文本框`
})); // -> '显示“Hello world!”的文本框
//例2
常量点={tag:'point',x:1,y:2}作为常量;
日志(匹配(点{
//只需要一个案例
点:({x,y})=>`A点位于(${x},${y})`
})); // -> '(1,2)处的点
一些期望的属性:
如果目前理论上不可能实现这一点,我想知道为什么以及是否有一种正在进行的语言功能可以实现这一点。结合了映射类型和条件(利用内置):
类型案例={
[K in V['tag']]:(V:Extract)=>R
}
函数匹配(值:V,案例:案例):R{
返回值(如有)[value.tag](值);
}
此签名将给出缺失案例的错误,推断案例的判别值类型(仅当首先键入=>
时,才会在操场中自动完成),并在指定为文本时引发缺失案例的错误
注意:由于常量
赋值,它将为您的形状
示例推断出比形状
更强的类型。在这种情况下,match
调用将引发一个关于额外大小写circle
的错误,但提供类型会显式地使其静音<代码>匹配(形状,{…})
更新
为了更好地推断返回类型,签名变得更加复杂,但可以这样做:
类型案例={
[K in V['tag']]:(V:Extract)=>any
}
键入OnlyKnownCases=C&Record&RecordNice!是否可以调整此类型,以便正确推断返回类型?现在,除非您显式指定它,否则它的计算结果似乎总是unknown
。更具体地说,我希望match
返回的类型是存储在适当标记下的case函数返回的所有类型的并集。对,但这需要显式指定返回的类型。还有其他一些情况,如constresult=match(x,{foo:=>1,bar:=>'2',baz:=>[3]}
其中正确的返回类型是1 |'2'| number[]
。如果能够推断出来,而不是明确地写出来,那会很方便。这让我彻夜未眠,但我认为它现在应该可以按预期工作了。谢谢你提出的这个非常有趣的问题。我很高兴,我不会作为一个包发布,但非常欢迎你来!