[英]TypeScript interface optional parameter but not viewed as optional
I have an interface that has a property that is optional, but it is set within my constructor with default values and then overridden with values passed in from the first parameter of the constructor.我有一个接口,它的属性是可选的,但它是在我的构造函数中使用默认值设置的,然后用从构造函数的第一个参数传入的值覆盖。 If the properties are not set the it uses the defaults.
如果未设置属性,则使用默认值。
How can I get it so that the parameter is still optional when passed in to the constructor, but when used within the class it is seen as set.我怎样才能得到它,以便参数在传递给构造函数时仍然是可选的,但是当在 class 中使用时,它被视为已设置。 I don't want to get the following error:
我不想收到以下错误:
Object is possibly 'undefined'.
Object 可能是“未定义”。
TypeScript Playground 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'
});
One approach would be to make the property non-optional, and then use a Partial<IMain>
to make the argument's all properties optional:一种方法是将属性设为非可选,然后使用
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";
}
}
You can mark the property as required for the class and change the constructor to this:您可以将属性标记为 class 所需的属性并将构造函数更改为:
export class ABC {
public main: Required<IMain>;
public constructor(main: IMain) {
this.main = {
...main,
prop: {
a: "A",
b: "B",
...main.prop
}};
}
}
If you have properties that should still be optional you have to be a bit more specific with your types.如果您的属性仍然是可选的,那么您必须对您的类型更加具体。 eg
例如
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
}};
}
}
Sometimes you might just want to define separate interfaces if this gets too complicated.有时,如果这变得太复杂,您可能只想定义单独的接口。 You can always extract the identical properties to a parent interface.
您始终可以将相同的属性提取到父界面。 eg
例如
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.