【问题标题】:Assign value to `readonly` properties from methods called by the constructor从构造函数调用的方法中为“只读”属性赋值
【发布时间】:2019-02-25 11:18:46
【问题描述】:

我有一个简单的类,我想在构造函数启动的方法中为只读属性赋值,但它显示[ts] Cannot assign to 'readOnlyProperty' because it is a constant or a read-only property. 为什么即使我从构造函数调用process,我也不能为属性赋值?

示例代码:

class C {
    readonly readOnlyProperty: string;
    constructor(raw: string) {
        this.process(raw);
    }
    process(raw: string) {
        this.readOnlyProperty = raw; // [ts] Cannot assign to 'readOnlyProperty' because it is a constant or a read-only property.
    }
}

【问题讨论】:

  • TypeScript 编译器应该如何推断出 process() 只会从构造函数中调用?

标签: typescript class constructor readonly-attribute


【解决方案1】:

我通常使用这种解决方法。

  private _myValue = true
  get myValue (): boolean { return this._myValue }

现在您可以从类内部更改属性,并且该属性从外部是只读的。此解决方法的一个优点是您可以重构属性名称而不会产生错误。这就是为什么我不会使用 (this as any).readOnlyProperty = raw 这样的东西。

【讨论】:

    【解决方案2】:

    除了“强制转换”this as any,您仍然可以通过仅修改此属性来强制执行类型检查:

    (this.readOnlyProperty as string) = raw; // OK
    (this.readOnlyProperty as string) = 5;   // TS2322: Type '5' is not assignable to type 'string'.
    
    

    【讨论】:

    • 我认为这是最干净最有效的答案
    【解决方案3】:

    当您创建一个单独的函数来分配值时,这个单独的函数可以在其他地方使用,而不是唯一的构造函数。编译器不会检查(对于公共函数,甚至无法检查)该函数是否仅从构造函数调用。所以错误。

    无论如何,您有 2 个解决方法来分配值。更清洁的方法是将单独函数的核心放入构造函数中。另一种会让你放松类型检查,因此不推荐除非你真的知道你在做什么,否则将this转换为any

    (this as any).readOnlyProperty = raw
    

    【讨论】:

      【解决方案4】:

      相当老的问题,但认为仍然值得分享我通常如何克服这个问题。我倾向于从方法中返回你想要设置的值,然后你仍然在分离逻辑,同时保持只读,没有任何可以说是非法的绕过。比如……

      class C {
          readonly readOnlyProperty: string;
          constructor(raw: string) {
              this.readOnlyProperty = this.process(raw);
          }
          process(raw: string) {
               // ...some logic that processes 'raw'...
      
              return raw;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多