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

Posted

技术标签:

【中文标题】对象可能是带有可选参数的 \'undefined\'.ts(2532)【英文标题】:Object is possibly 'undefined'.ts(2532) with optional arguments对象可能是带有可选参数的 'undefined'.ts(2532) 【发布时间】:2021-02-03 13:38:50 【问题描述】:

我有这个代码:

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
  

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

我想应该有一种可能的方法来拥有一个带有可选参数的函数/类,并在告诉编译器该参数已实际传入或没有传入后,未定义的场景已得到相应的管理。

如何使用可选参数来处理?

编辑:根据我的研究,从here 获取代码示例,不可能让你的类变量可选并且让编译器知道它们不会是未定义的并在你的方法中使用它们,而不需要分开参数的类型,使这种类型的参数是可选的,而类变量不是可选的,如果类很大,这有点冗长。我想确认这是否是处理打字稿类中的可选参数的有效方法或最佳方法。

【问题讨论】:

既然你肯定在构造函数中分配了私有字段,你可以去掉它们的问号。 所以问号只适用于构造函数参数? 在这种情况下是正确的。 【参考方案1】:

编译器抱怨是因为您将该属性定义为? 的可选属性。问题在于您的声明。

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

我什么时候希望类属性是可选的?

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

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

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

【讨论】:

对于我的具体情况,我想要重载构造函数行为,以便构造函数获取可选参数,但这样我就可以在类方法中使用这些参数而不会出现 ts(2532) 错误。我实现了使用构造函数参数类型的参数可选的不同类型,然后不将类属性标记为可选(这是没有问号的)。有点冗长,但完成了工作。 (冗长,因为您需要为创建的类型标记所有类变量问题)。想知道是否有更清洁或更直接的方法。 在我对这个问题的回答中提供了更多详细信息,并使用示例代码来解决我正在提出的问题,因为用代码本身比用文字更好地表达它:***.com/questions/12702548/…【参考方案2】:

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

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!
  

【讨论】:

好的,非常感谢!我关心的是澄清这一点,如果您将参数设为可选时的方法,因为如果类很大,必须两次声明类型会使它有点冗长,这似乎是问号的重点。但是目前看来这将是正确的方法:)

以上是关于对象可能是带有可选参数的 'undefined'.ts(2532)的主要内容,如果未能解决你的问题,请参考以下文章

(参数) children: ReactNode 对象可能是 'null' 或 'undefined'

Javascript - 带有可选参数作为对象的函数?

带有可选参数的类初始化 - 不可能?

如何获取可选参数的默认值?

Javascript函数的模板,带有作为对象传递的可选和必需参数

从 C++ 调用带有可选参数的 Fortran 子例程