【问题标题】:Class not inheriting property initialization status类不继承属性初始化状态
【发布时间】:2019-09-05 21:47:26
【问题描述】:

我有这种情况,当我继承一个类时,基类中的属性不会被识别为在扩展类中初始化。我不确定这是否是 typescript 或 tslint 的问题,我在谷歌上找不到任何东西(可能没有搜索到正确的东西)。

(属性)BaseClass.myProperty:IMyProperty |未定义的对象是 可能是“未定义”.ts(2532)

tsconfig.json

{
  "compilerOptions": {
    "strict": true
  }
}

example.ts

interface IMyProperty{
  myName: string;
}

class BaseClass {
  readonly myProperty: IMyProperty | undefined;
  constructor(options: IMyProperty){
    this.myProperty = options
  }
}

class ExtendedClass extends BaseClass{
  constructor(options: IMyProperty){
    super(options)
  }

  printMyName(){
    console.log(this.myProperty.myName); // <-- Complains about this
  }
}

const extendedClass = new ExtendedClass({myName: 'John Smith'});
extendedClass.printMyName();

【问题讨论】:

    标签: node.js typescript


    【解决方案1】:

    我想这种方法可以解决这个问题,但看起来仍然不是很优雅

    interface IMyProperty {
        myName: string;
    }
    
    class BaseClass {
        readonly myProperty: IMyProperty | undefined;
        constructor(options: IMyProperty) {
            this.myProperty = options
        }
    }
    
    class ExtendedClass extends BaseClass {
        readonly myProperty: IMyProperty;
    
        constructor(options: IMyProperty) {
            super(options);
            this.myProperty = options;
        }
    
        printMyName() {
            console.log(this.myProperty.myName);
        }
    }
    
    const extendedClass = new ExtendedClass({ myName: 'John Smith' });
    extendedClass.printMyName();
    

    【讨论】:

      【解决方案2】:

      在您的 console.log() 语句中,您尝试记录 myName,但正如编译器错误所说,this.myProperty 可能未定义。因此,不允许使用此语句,因为您无法访问未定义对象 (this.myProperty) 的属性 (myName)。

      为什么myProperty 可以完全未定义?您可以删除 BaseClass 中的 | undefined 吗?这将解决您的问题。

      【讨论】:

      • 它正在从类外初始化。我希望 BaseClass.myProperty 无法定义,但 ExtendedClass 的所有实例都应该期望 myProperty 初始化。
      • 那么正如 Mateusz 所说,您应该使用非空断言运算符!,或者断言myPropertyExtendedClass 构造函数或printMyName() 中没有未定义
      • 不幸的是,即使我在扩展类中声明它,我仍然必须在扩展类中显式分配它。即使基类已经这样做了。
      【解决方案3】:

      因为您声明 myProperty 可以是未定义的,所以 TypeScript 必须抱怨访问可能未定义的值。这是因为 TS 无法知道您是否没有在代码中的其他位置重新分配值。

      const extendedClass = new ExtendedClass({myName: 'John Smith'});
      extendedClass.myProperty = undefined
      extendedClass.printMyName(); // Would throw a runtime error.
      

      为了解决这个问题,你必须添加一个保护检查值是否在执行时正确定义。

      class ExtendedClass extends BaseClass {
        printMyName() {
          // if (this.myProperty) { ... } would also work.
          if (typeof this.myProperty !== 'undefined') {
            console.log(this.myProperty.myName); // Now it works. TS know it can't be undefined at this point.
          }
        }
      }
      

      【讨论】:

      • 对不起,我忘了说我设置为只读。我真的不想添加警卫,因为该属性将被大量使用。如果它使用 BaseClass 构造函数,它也不会抱怨。
      • readonly 不能保证运行时代码不会改变任何东西,所以 TS 仍然是正确的。试试extendedClass['my' + 'Property'] = undefined,看看它会起作用。如果您确实确定不想保护代码,可以使用! 来确保关于属性存在的 TS:this.myProperty!.myName
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      相关资源
      最近更新 更多