“删除”运算符的操作数必须是可选的/对象在角度 12 中可能存在“未定义”错误

BHL*_*BHL 2 typescript angular

所以我正在以角度创建警报服务,但无法克服此错误。我知道可以通过在 ts.config 文件中禁用严格的空检查来抑制此错误。但不想采取这种方法尝试过操作符使其成为可选,但它仍然不起作用,我不确定我是否将操作符放在正确的位置,我是角度新手,任何指导都会非常有帮助,谢谢

 alerts: Alert[] = [];

 this.alerts!.find(x => x === alert).fade = true;

Run Code Online (Sandbox Code Playgroud)

警报模型.ts

export class Alert {
   public id!: string;
   public type!: AlertType;
   public message!: string;
   public autoClose!: boolean;
   public keepAfterRouteChange!: boolean;
   public fade!: boolean;

    constructor(init?:Partial<Alert>) {
        Object.assign(this, init);
    }
}

export enum AlertType {
    Success,
    Error,
    Info,
    Warning
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

在此输入图像描述

enk*_*tor 6

有两种不同的错误,都与称为严格 null 检查的TypeScript 功能有关。

删除明确需要的属性

在尝试修复错误之前,我们需要了解导致此错误的原因。否则事情会很快脱轨。我们看第一条消息:

“删除”运算符的操作数必须是可选的

TypeScript 允许开发人员描述一组必须遵守的规则。然后,它根据这些规则检查代码,以使其更加一致且不易出错。

我们通过在代码中将其标记为非可选来表示“我的对象必须具有此属性”:

export class Alert {
  public keepAfterRouteChange!: boolean;
Run Code Online (Sandbox Code Playgroud)

然后我们尝试删除这个属性,明确打破上述规则:

delete x.keepAfterRouteChange
Run Code Online (Sandbox Code Playgroud)

相反,我们应该回答“这个属性实际上是可选的吗?”的问题。并将其标记为可选(通过在声明中使用问号:)keepAfterRouteChange?: boolean或从不将其从对象中删除。只需分配一个false值即可:

x.keepAfterRouteChange = false
Run Code Online (Sandbox Code Playgroud)

尝试访问以下属性undefined

第二条消息是

对象可能是“未定义”

根据MDN, find() 方法可以返回undefined

如果没有值满足测试函数,undefined则返回。

我们无法访问.fade未定义值的属性。如果关闭严格的空检查,我们会在运行时收到一条错误消息:

未捕获的类型错误:无法设置未定义的属性“淡入淡出”

幸运的是,TypeScript 甚至在启动代码之前就警告我们正在发生一些可疑的事情。为了让事情变得不那么可疑,我们必须检查我们正在寻找的值是否确实找到了。

然而,在这个特定的代码中,我们已经有了我们正在尝试查找和变异的值。它存储在value变量中:

this.alerts!.find(x => x === alert).fade = true;
Run Code Online (Sandbox Code Playgroud)

因此根本不需要搜索值,我们可以改变alert对象本身:

alert.fade = true
Run Code Online (Sandbox Code Playgroud)

尽可能少使用 bang 运算符

使用感叹号来假设非空值被认为是一种不好的做法,应该避免。当严格的空检查模式打开时,类声明中没有任何意义。所以而不是

export class Alert {
  public id!: string;
  public type!: AlertType;
  public message!: string;
  public autoClose!: boolean;
  public keepAfterRouteChange!: boolean;
  public fade!: boolean;
Run Code Online (Sandbox Code Playgroud)

你可以直接写,不带感叹号:

export class Alert {
  public id: string;
  public type: AlertType;
  public message: string;
  public autoClose: boolean;
  public keepAfterRouteChange: boolean;
  public fade: boolean;
Run Code Online (Sandbox Code Playgroud)

另外,不是说必须找到一个值

this.alerts.find(myFunction)!.fade = true;
Run Code Online (Sandbox Code Playgroud)

您应该检查是否确实找到了某个值:

const fadingAlert = this.alerts.find(myFunction)
if (fadingAlert) {
  fadingAlert.fade = true;
}
Run Code Online (Sandbox Code Playgroud)