TypeScript条件类型和类型防护

时间:2018-11-27 16:38:08

标签: typescript types conditional

我在结合TypeScript的类型保护和条件类型时遇到一些问题。考虑:

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'.
}

我希望doAThing函数接受IThisThingIThatThing并返回与其接收的相同类型。 las,编译器在以下消息中令人窒息:

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

有人可以让我挺直吗?我觉得我已经接近了,但还不太正确。我在此博客文章中使用第一个示例(看起来很相似):http://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/

2 个答案:

答案 0 :(得分:0)

Typescript不允许您将任何内容分配给仍具有自由类型参数的条件类型,只是不支持。最好的选择是拥有一个具有泛型和条件类型的签名,以及一个更简单的实现签名,该签名返回两种可能性的结合

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;
}

答案 1 :(得分:0)

只需返回T

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