簡體   English   中英

TypeScript接口可選參數但不視為可選

[英]TypeScript interface optional parameter but not viewed as optional

我有一個接口,它的屬性是可選的,但它是在我的構造函數中使用默認值設置的,然后用從構造函數的第一個參數傳入的值覆蓋。 如果未設置屬性,則使用默認值。

我怎樣才能得到它,以便參數在傳遞給構造函數時仍然是可選的,但是當在 class 中使用時,它被視為已設置。 我不想收到以下錯誤:

Object 可能是“未定義”。

TypeScript 游樂場

export interface IMain {
  req: string;
  prop?: ISecondary;
}

export interface ISecondary {
  a?: string;
  b?: string;
}
export class ABC {
  public main: Main;

  public constructor(main: Main) {
    this.main.prop = {
      a: "A",
      b: "B",
      ...main.prop
    };
  }

  public doSomething() {
    this.main.prop.a = "Z";
  }
}

new ABC({
  req: 'cat'
});

一種方法是將屬性設為非可選,然后使用Partial<IMain>將參數的所有屬性設為可選:

export interface IMain {
  prop: ISecondary;
}

export interface ISecondary {
  a?: string;
  b?: string;
}

const ISecondaryDefaults: ISecondary = {
  a: "A",
  b: "B",
};

export class ABC {
  public main: IMain;

  public constructor(main: Partial<IMain>) {
    this.main = {
      ...main,
      prop: {
        ...ISecondaryDefaults,
        ...main.prop,
      },
    };
  }

  public doSomething() {
    this.main.prop.a = "Z";
  }
}

您可以將屬性標記為 class 所需的屬性並將構造函數更改為:

export class ABC {
    public main: Required<IMain>;

    public constructor(main: IMain) {
        this.main = {
            ...main,
            prop: {
                a: "A",
                b: "B",
                ...main.prop
        }};
    }
}

如果您的屬性仍然是可選的,那么您必須對您的類型更加具體。 例如

type OptionalProps<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>

export interface IMain {
    req: string;
    prop: ISecondary; // Required here
}

export class ABC {
    public main: IMain;

    public constructor(main: OptionalProps<IMain, 'prop'>) {
        this.main = {
            ...main,
            prop: {
                a: "A",
                b: "B",
                ...main.prop
        }};
    }
}

有時,如果這變得太復雜,您可能只想定義單獨的接口。 您始終可以將相同的屬性提取到父界面。 例如

interface IMainRequired {
    req: string;
}
interface IMainOptional {
    prop: ISecondary;
}
export type IMain = IMainRequired & IMainOptional
export type IMainArg = IMainRequired & Partial<IMainOptional>

export class ABC {
    public main: IMain;

    public constructor(main: IMainArg) {
        this.main = {
            ...main,
            prop: {
                a: "A",
                b: "B",
                ...main.prop
        }};
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM