【问题标题】:TypeScript Error: Getter-only property not defined in literalTypeScript 错误:Getter-only 属性未在文字中定义
【发布时间】:2019-03-16 13:43:19
【问题描述】:

这感觉像是一个非常愚蠢的错误,但我有一个打字稿类:

export class Stat{
    abbr: StatType;
    score: number;
    mod: number;
    get name(): string { return StatType[this.abbr]; }
}

“name”属性是只读的,对吗?

但是,在模拟一些“统计信息”时,我得到了我没有定义“名称”的错误。

const stats: Stat[] = [{
    abbr: StatType.Str,
    score: 15,
    mod: 2
}]

这会产生错误:error TS2741: Property 'name' is missing in type '{ abbr: StatType.Str; score: number; mod: number; }' but required in type 'Stat' 但是如果属性“name”是只读的,为什么我必须为它分配一个值?

如果我分配了一个值,然后使用该值,则 get() 属性将被完全忽略。

我做错了吗?如何让 TS 相信我不需要提供 name 属性?

枚举是这样定义的:

export enum StatType{
    Str,
    Dex,
    Con,
    Int,
    Wis,
    Cha
}

谢谢!

【问题讨论】:

    标签: typescript


    【解决方案1】:

    LAST EDIT:嗯,所以技术上编辑答案有效,但是对象没有转换为 Stat,所以它没有实现吸气剂。它“有效”(就 TS 而言),但 getter 是未定义的,除非我手动将它添加到对象中。 (我的浏览器一定有脏缓存什么的。)

    所以我最终做的是创建一个“模拟”服务,它可以为我存根对象。我不必将它注入任何类或任何东西,我可以在类之外声明它(只需新建),并使用它来生成我想要的对象。这给了我:拥有我的实际对象(带有getter)的能力,我的对象的空构造函数,并且我没有弄脏我的服务类(尽管我弄脏了文件......当我实现http)。

    ...此时,实现 http 可能会更快。

    编辑: 好的,这就是真正的答案:只需 cast json 对象。如果这样做,我不需要仅为测试数据定义构造函数,也不需要定义每个属性/函数。

    let statTest = <Stat>({
        abbr: StatType.Con,
        score: 12,
        mod: 1
    });
    

    原答案:

    所以it turns out 您需要使用 new() 语法实际创建对象。但由于 TS 缺少初始化列表,您必须创建显式构造函数,并手动提供所有参数。

    所以我的班级变成了:

    export class Stat{
        abbr: StatType;
        score: number;
        mod: number;
        constructor(statType: StatType, score: number, mod: number){
            this.abbr = statType;
            this.score = score;
            this.mod = mod;
        }
        get name(): string { return StatType[this.abbr]; }
    }
    

    我的数组变成了:

    const stats: Stat[] = [
        new Stat(StatType.Str, 15, 2)
    ]
    

    哦,好吧,当值来自实际服务器时,我认为这并不重要。

    【讨论】:

      【解决方案2】:

      当您创建 gettersetter 时,typescript 将为您生成以下代码:

      export class Stat{
          abbr: StatType;
          score: number;
          mod: number;
          _name: string
      
      Object.defineProperty(foo.prototype, "name", {
              get: function () {
                  return  { return StatType[this.abbr]; };
              },
              set: function (theName) {
                  this._name = theName;
              },
              enumerable: true,
              configurable: true
          });
      }
      

      您可以通过像这样覆盖默认行为来解决此问题:

      export class Stat{
          abbr: StatType;
          score: number;
          mod: number;
           Object.defineProperty(this,'name',{
                     get(){return StatType[this.abbr]; }
                    });
      }
      

      【讨论】:

      • 原来如果把get改成普通函数,TS还是报错。没有尝试 Object.defineProperty,因为没有理由需要在那里。
      • @emery.noel '没有理由需要在那里'是什么意思?看来这正是您正在寻找的:/
      • 不,我希望在开始从服务器获取数据之前定义一个类,并为示例数据实例化它。这是不必要的迟钝。已经有定义 getter 的语法。我想我真正想要的是一个“相信我,这将起作用”标志或其他东西,以关闭 TS 编译器。不过,我很感激!如果我真的需要将一个常量 json 字符串转换为“stats”,那么是的,这可能会起作用。
      猜你喜欢
      • 2019-03-30
      • 2021-11-27
      • 2020-04-30
      • 2012-12-29
      • 1970-01-01
      • 2023-01-15
      • 2020-06-16
      • 1970-01-01
      • 2018-04-03
      相关资源
      最近更新 更多