Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.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_Discriminated Union - Fatal编程技术网

Typescript 泛型判别并

Typescript 泛型判别并,typescript,discriminated-union,Typescript,Discriminated Union,我希望能够使用通用的。但是,它似乎不起作用: 示例代码(: 接口Foo{ 类型:“foo”; fooProp:string } 接口条{ 类型:'bar' barProp:数字 } 接口生成{ 项目:T; } 设func=(genericThing:genericThing)=>{ if(genericThing.item.type==='foo'){ genericThing.item.fooProp;//这可以工作,但genericThing的类型仍然是genericThing 让fooTh

我希望能够使用通用的。但是,它似乎不起作用:

示例代码(:

接口Foo{
类型:“foo”;
fooProp:string
}
接口条{
类型:'bar'
barProp:数字
}
接口生成{
项目:T;
}
设func=(genericThing:genericThing)=>{
if(genericThing.item.type==='foo'){
genericThing.item.fooProp;//这可以工作,但genericThing的类型仍然是genericThing
让fooThing=genericing;
fooThing.item.fooProp;//错误!
}
}
我希望typescript能够认识到,由于我对generic
属性进行了区分,因此
generitching
必须是
generitching

我猜这就是不被支持


另外,有点奇怪的是,在直接赋值之后,
fooThing.item
失去了辨别力。

表达式
generiching.item
被视为
if
块中的
Foo
。我认为它只有在将其提取到变量后才能工作(
const item=genericThing.item
)。可能是最新版本TS的更好表现

这将启用模式匹配,如上的官方文档中的函数
区域
,这在C#中实际上是缺失的(在v7中,像这样的
开关
语句中仍然需要
默认
情况)

事实上,奇怪的是,
genericThing
仍然没有被区分(作为
genericThing
而不是
genericThing
),即使在
if
块中,
item
Foo
!那么
fooThing.item.fooProp;
的错误也不会让我感到惊讶

我想TypeScript团队还需要做一些改进来支持这种情况。

问题 受歧视工会中的类型缩小受到若干限制:

不展开仿制药

首先,如果类型是泛型的,则泛型不会展开以缩小类型:缩小需要一个并集才能工作。例如,这不起作用:

let func = (genericThing:  GenericThing<'foo' | 'bar'>) => {
    switch (genericThing.item) {
        case 'foo':
            genericThing; // still GenericThing<'foo' | 'bar'>
            break;
        case 'bar':
            genericThing; // still GenericThing<'foo' | 'bar'>
            break;
    }
}

最后一行出现了什么错误?仅仅从泛型中提取项,无论是在函数顶部还是通过在参数中进行分解,都会有什么不同吗?@jornsharpe打开typescript游乐场链接,您可以看到它。
fooProp在type上不存在…
oh,伙计……这个解决方案很粗糙!很好知道但这是可能的。我的解决方案只是针对嵌套对象编写代码,而不是尝试接受狭窄的泛型。例如:让我的函数接受
Foo
(如果我需要做一些有区别的事情,则直接接受
GenericThing
)it@NSjonas这也是一个选项:-)
let func = (genericThing:  GenericThing<'foo' | 'bar'>) => {
    switch (genericThing.item) {
        case 'foo':
            genericThing; // still GenericThing<'foo' | 'bar'>
            break;
        case 'bar':
            genericThing; // still GenericThing<'foo' | 'bar'>
            break;
    }
}
let func = (genericThing: GenericThing<'foo'> | GenericThing<'bar'>) => {
    switch (genericThing.item) {
        case 'foo':
            genericThing; // now GenericThing<'foo'> !
            break;
        case 'bar':
            genericThing; // now  GenericThing<'bar'> !
            break;
    }
}
let func = (genericThing: GenericThing<{ type: 'foo' }> | GenericThing<{ type: 'bar' }>) => {
    switch (genericThing.item.type) {
        case 'foo':
            genericThing; // still GenericThing<{ type: 'foo' }> | GenericThing<{ type: 'bar' }>)
            genericThing.item // but this is { type: 'foo' } !
            break;
        case 'bar':
            genericThing;  // still GenericThing<{ type: 'foo' }> | GenericThing<{ type: 'bar' }>)
            genericThing.item // but this is { type: 'bar' } !
            break;
    }
}
function isOfType<T extends { type: any }, TValue extends string>(
  genericThing: GenericThing<T>,
  type: TValue
): genericThing is GenericThing<Extract<T, { type: TValue }>> {
  return genericThing.item.type === type;
}

let func = (genericThing: GenericThing<Foo | Bar>) => {
  if (isOfType(genericThing, "foo")) {
    genericThing.item.fooProp;

    let fooThing = genericThing;
    fooThing.item.fooProp;
  }
};