代码之家  ›  专栏  ›  技术社区  ›  Michał Miszczyszyn

使用区分的联合类型时出现Typescript错误

  •  0
  • Michał Miszczyszyn  · 技术社区  · 5 年前

    我试图在typescript中使用区分联合类型,但出现以下错误:

    Type '{ data: Aaaa | Bbbb; type: "aaaa" | "bbbb"; }' is not assignable to type 'EventData'.
      Type '{ data: Aaaa | Bbbb; type: "aaaa" | "bbbb"; }' is not assignable to type '{ type: "bbbb"; data: Bbbb; }'.
        Types of property 'type' are incompatible.
          Type '"aaaa" | "bbbb"' is not assignable to type '"bbbb"'.
            Type '"aaaa"' is not assignable to type '"bbbb"'.
    

    使用以下代码:

    export type Aaaa = {
        aPropForA: string
    }
    
    export type Bbbb = {
        somePropsB: number
    }
    
    export type EventData =
      | { type: 'aaaa'; data: Aaaa }
      | { type: 'bbbb'; data: Bbbb }
    
    // simulate getting the data for brevity
    declare const data: EventData['data'];
    declare const type: EventData['type'];
    
    export const getEventData = (): EventData => {
      return { // why is there an error?
        data,
        type,
      }
    }
    

    live

    问题的根源是什么?我怎么能不打字就把它修好呢?

    1 回复  |  直到 5 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    5 年前

    这是一个错误的原因是没有什么能保证 data type 是正确的。在本代码中,赋值是有效的,并且会导致不正确的联合:

    const data: EventData['data'] = { aPropForA: ""};
    const type: EventData['type'] = "bbbb"
    
    export const getEventData = (): EventData => {
      return { // why is there an error?
        data,
        type,
      }
    }
    

    在没有类型断言的情况下绕过错误的唯一方法是进行所需的检查:

    declare const data: EventData['data'];
    declare const type: EventData['type'];
    
    export const getEventData = (): EventData => {
      if(type === 'aaaa' && 'aPropForA' in data) {
        return { data, type,}
      } else if(type === 'bbbb' && 'somePropsB' in data) { 
        return { data, type,}
      }
      throw new Error("Invalid combination")
    }