在Typescript中接受相似接口的两个版本

I'm trying to build stronger types for an interface that I currently can't change (too big a task). The interface should either allow {a: string, x: number} or {b: string, x: number} but not {a: 'a', b: 'b', x: 1}. My Typescript version is 3.9.2.

我已经尝试了两种不同的联合类型

type IType = {a: string, b: never, x: number} | {a: never, b: string, x: number}

and for {a: 'a', x: 1} it keeps complaining about b missing and if I remove the never lines it says that a is not defined on the type.

我也尝试了XOR助手类型,但没有成功。

Is there a way to get what I want? I currently have to resort to {a?: string, b?: string, x: number}

评论
  • 终淡化了美
    终淡化了美 回复

    I think you just need to make those never properties optional:

    type IType = {a: string, b?: never, x: number} | {a?: never, b: string, x: number}
    
    const thing: IType = {a: 'a', x: 1};
    const thing2: IType = {b: 'b', x: 1};
    const thing3: IType = {a: 'a', b: 'b', x: 1}; // error
    

    Playground link

    Be aware that this will allow you to do an explicit undefined:

    const thing: IType = {a: 'a', x: 1, b: undefined}; // legal