Typescript接口条件可选参数

Mil*_*lad 5 typescript

我们可以做到这一点:

interface IMyInterface{
    firstname:string  // this means firstname is mandatory

    name:string  // this also means name is mandatory
}
Run Code Online (Sandbox Code Playgroud)

我该怎么说,firstname还是name可选(?),取决于是否提供了另一个?

或者,如果那不可能,还有哪些其他选择?

编辑:这不是Typescript接口的重复-可能需要“一个或另一个”属性吗?

我们不想为每个可选元素创建一个单独的接口,仅仅是因为维护,命名和重构会很麻烦,并且不可重用。

Cat*_*yst 9

这是说“OneOf”这些键的通用方式,您可以在此处使用它:

type EachOfTmp<T> = {// to make OneOf less gross
  [K in Keys<T>]: {
    _: {[X in K]: T[K]};
  }
};

// require only one of the keys
export type OneOf<T> = EachOfTmp<T>[Keys<T>]["_"] & Partial<T>;

const thing1: OneOf<{ a: number; b: number }> = { a: 2 } // valid
const thing2: OneOf<{ a: number; b: number }> = { b: 2 } // valid
const thing3: OneOf<{ a: number; b: number }> = {} // invalid
Run Code Online (Sandbox Code Playgroud)

编辑:哎呀,我忘了我用这个方便的钥匙交易 -

export type Keys<T> = keyof T;
export function Keys<T>(o: T) {
  if (!o) {
    return [];
  }
  return Object.keys(o) as Keys<T>[];
}
Run Code Online (Sandbox Code Playgroud)


Pav*_*vel 5

其它的办法:

    interface IName {
        name:string 
    }

    interface IFirstName {
        firstname:string 
    }

    let x: IName | IFirstName;
    x = {}; // Error
    x = { name: "" }; // Ok
    x = { firstname: "" }; // Ok
    x = { name: "", firstname: "" }; // Ok
Run Code Online (Sandbox Code Playgroud)