对象可能是带有可选参数的 'undefined'.ts(2532)

Object is possibly 'undefined'.ts(2532) with optional arguments

我有这个代码:

export default class MyRandomClass {
  private posFloat32Array?: Float32Array;
  private otherArgument?: number;

  constructor(params:MyRandomClass = {} as MyRandomClass) {
    const {
      posFloat32Array,
      otherArgument,
    } = params;

    this.posFloat32Array = (posFloat32Array !== undefined) ? posFloat32Array : new Float32Array();
    this.otherArgument = (otherArgument !== undefined) ? otherArgument : 0;
  }

  classMethod():void {
    const total = this.posFloat32Array?.length + 3; //error
  }
}

对象不可能是未定义的,但我仍然收到错误。 我的目的是有一个 class 可以用不同方式提供的参数构造,这样输出数据将始终相同。这是在 this 示例中模拟构造函数重载。

我想应该有一种可能的方法来让 function/class 带有可选参数,并在告诉编译器参数实际上已经传入或者如果没有传入之后,未定义的场景已经相应地进行了管理。

如何使用可选参数处理这个问题?

编辑:根据我的研究,以 here 中的代码示例为例,不可能使您的 class 变量可选并让编译器知道它们不会未定义并使用它们在你的方法中,没有为参数创建一个单独的类型,使这个类型的参数可选并且 class 变量不是可选的,如果 class 很大,这有点冗长。我想确认这是处理打字稿中可选参数的有效方法还是最佳方法 classes.

编译器报错是因为您将 属性 定义为与 ? 可选的。问题出在你的声明上。

由于您有一个构造函数,并且 posFloat32ArrayotherArgument 始终在构造函数中设置为显式值,因此不需要将这些属性标记为可选。您应该删除将这些属性标记为可选的。

When would I want class properties to be optional then?

这是一个很好的问题!如果您没有显式实现构造函数,或者您没有在构造函数中显式设置这些值,此时您可能希望将 属性 标记为可选。例如,下面的 class 示例可以在没有明确定义这些值的情况下实例化。将它们标记为可选可能是一个很好的用例。

class MyRandomClass {
  private posFloat32Array?: Float32Array;
  private otherArgument?: number;

  classMethod():void {
    const total = this.posFloat32Array?.length ?? 0 + 3;
  }
}

您需要分离您的接口,因为 class 不再描述传入参数对象。我的回答显示了一种更优雅的设置默认值的方式。由于您正在设置默认值,因此界面上的参数是可选的,但它们在 class 内得到保证(注意问号已移动的位置)。这应该适合你:

interface MyNotSoRandomInterface {
  posFloat32Array?: Float32Array;
  otherArgument?: number;
}

export default class MyRandomClass {
  private posFloat32Array: Float32Array;
  private otherArgument: number;

  constructor(params:MyNotSoRandomInterface = {} as MyNotSoRandomInterface) {
    const {
      posFloat32Array =  new Float32Array(),
      otherArgument = 0,
    } = params;

    this.posFloat32Array = posFloat32Array;
    this.otherArgument = otherArgument;
  }

  classMethod():void {
    const total = this.posFloat32Array.length + 3; //no errors!
  }
}