繁体   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