[英]TypeScript interface optional parameter but not viewed as optional
我有一个接口,它的属性是可选的,但它是在我的构造函数中使用默认值设置的,然后用从构造函数的第一个参数传入的值覆盖。 如果未设置属性,则使用默认值。
我怎样才能得到它,以便参数在传递给构造函数时仍然是可选的,但是当在 class 中使用时,它被视为已设置。 我不想收到以下错误:
Object 可能是“未定义”。
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.