简体   繁体   English

TypeScript 条件类型和类型保护

[英]TypeScript Conditional Types and Type Guards

I'm having some problems combining TypeScript's type guards and conditional types.我在结合 TypeScript 的类型保护和条件类型时遇到了一些问题。 Consider:考虑:

export interface IThisThing {
    someProp: number;
}

export function isIThisThing(type: any): type is IThisThing { 
    return !!type.someProp;
}

export interface IThatThing {
    someOtherProp: string;
}

export function isIThatThing(type: any): type is IThatThing { 
    return !!type.someOtherProp;
}

function doAThing<T extends IThisThing | IThatThing>(
    data: T
): T extends IThisThing ? IThisThing : IThatThing {
    if (isIThisThing(data)) { 
        return data; // Type 'T & IThisThing' is not assignable to type 'T extends IThisThing ? IThisThing : IThatThing'.
    };
    return data; // Type 'T' is not assignable to type 'T extends IThisThing ? IThisThing : IThatThing'.
                 //   Type 'IThisThing | IThatThing' is not assignable to type 'T extends IThisThing ? IThisThing : IThatThing'.
                 //     Type 'IThisThing' is not assignable to type 'T extends IThisThing ? IThisThing : IThatThing'.
}

I'd expect the doAThing function to accept IThisThing or IThatThing and to return the same type as it receives.我希望doAThing函数接受IThisThingIThatThing并返回与它接收到的相同的类型。 Alas the compiler chokes with messages along the line of:唉,编译器被以下信息窒息:

Type 'T & IThisThing' is not assignable to type 'T extends IThisThing ? IThisThing : IThatThing'.

Can someone set me straight?有人可以让我直截了当吗? I feel I'm close but not quite getting it right.我觉得我很接近但还没有完全正确。 I'm using the first example (which seems pretty similar) in this blog post: http://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/我在这篇博文中使用了第一个例子(看起来很相似): http : //artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/

Typescript will not let you assign anything to a conditional type that still has free type parameter, it's just not supported. Typescript 不允许您将任何内容分配给仍然具有自由类型参数的条件类型,它只是不受支持。 Your best bet is to have a signature with the generics and the conditional type and a simpler implementation signature that returns a union of the two possibilities最好的办法是有一个带有泛型和条件类型的签名以及一个更简单的实现签名,它返回两种可能性的联合

export interface IThisThing {
    someProp: number;
}

export function isIThisThing(type: any): type is IThisThing { 
    return !!type.someProp;
}

export interface IThatThing {
    someOtherProp: string;
}

export function isIThatThing(type: any): type is IThatThing { 
    return !!type.someOtherProp;
}

function doAThing<T extends IThisThing | IThatThing>(
    data: T
): T extends IThisThing ? IThisThing : IThatThing
function doAThing(
    data: IThisThing | IThatThing
): IThisThing | IThatThing {
    if (isIThisThing(data)) { 
        return data;
    };
  return data;
}

Just return T :只需返回T

function doAThing<T extends IThisThing | IThatThing>(
    data: T
): T {
    if (isIThisThing(data)) { 
        return data
    } else {
        return data;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM