Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jsp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 什么';标记的联合体的通用匹配函数的正确类型是什么?_Typescript - Fatal编程技术网

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)处的点
一些期望的属性:

  • 应验证每个可能的标记是否具有相应的case函数
  • 应根据值的类型自动完成第二个参数中的标记名
  • 不应要求显式的泛型参数
  • 更新:应将返回的类型正确推断为所有可能类型的并集

  • 如果目前理论上不可能实现这一点,我想知道为什么以及是否有一种正在进行的语言功能可以实现这一点。

    结合了映射类型和条件(利用内置):

    类型案例={
    [K in V['tag']]:(V:Extract)=>R
    }
    函数匹配(值:V,案例:案例):R{
    返回值(如有)[value.tag](值);
    }
    
    此签名将给出缺失案例的错误,推断案例的判别值类型(仅当首先键入
    =>
    时,才会在操场中自动完成),并在指定为文本时引发缺失案例的错误

    注意:由于
    常量
    赋值,它将为您的
    形状
    示例推断出比
    形状
    更强的类型。在这种情况下,
    match
    调用将引发一个关于额外大小写
    circle
    的错误,但提供类型会显式地使其静音<代码>匹配(形状,{…})

    更新 为了更好地推断返回类型,签名变得更加复杂,但可以这样做:

    类型案例={
    [K in V['tag']]:(V:Extract)=>any
    }
    
    键入OnlyKnownCases=C&Record&Record

    Nice!是否可以调整此类型,以便正确推断返回类型?现在,除非您显式指定它,否则它的计算结果似乎总是
    unknown
    。更具体地说,我希望
    match
    返回的类型是存储在适当标记下的case函数返回的所有类型的并集。对,但这需要显式指定返回的类型。还有其他一些情况,如
    constresult=match(x,{foo:=>1,bar:=>'2',baz:=>[3]}
    其中正确的返回类型是
    1 |'2'| number[]
    。如果能够推断出来,而不是明确地写出来,那会很方便。这让我彻夜未眠,但我认为它现在应该可以按预期工作了。谢谢你提出的这个非常有趣的问题。我很高兴,我不会作为一个包发布,但非常欢迎你来!