使用TypeScript和Ember编写计算属性的正确方法是什么?

pba*_*nka 3 ember.js typescript

我有一个相对较小的Ember/TypeScript应用程序,我已经工作了大约六个月.我曾经用如下定义计算属性:

   @computed('styleNamespace', 'status')
   statusClass(componentClassName: string, status: string): string {
     return `${componentClassName}--${status}`
   }
Run Code Online (Sandbox Code Playgroud)

但是我从来没有能够正确地通过TypeScript检查.在回顾了Chris Krycho的Emberconf培训材料后,似乎"正确"的方法如下:

   @computed('styleNamespace', 'status')
   get statusClass(this: CertificateCard): string {
     return `${this.get('styleNamespace')}--${this.get('status')}`
   }
Run Code Online (Sandbox Code Playgroud)

它是否正确?我似乎错过了什么,但因为我仍然得到这样的错误:

Error: Assertion Failed: Attempted to apply @computed to statusClass,
but it is not a native accessor function. 
Try converting it to `get statusClass()`
Run Code Online (Sandbox Code Playgroud)

Chr*_*cho 6

要使装饰器与Ember.js中的TypeScript一起使用,您至少需要使用ember-decorators 2.0.0(在本答复时可用2.0.0-beta.2)并"experimentalDecorators": true"compilerOptions"您的部分中设置tsconfig.json.

然后,对于3.1之前的所有Ember版本,你将像这样编写计算机(如第二个例子中所示,但是对于后来偶然发现的其他人来说更完整地写出来).请注意,我们并不需要返回类型的吸气剂,因为它可以通过打字稿正确推断的(不像经典的灰烬计算财产回调,在返回类型要求是明确的).

import Component from '@ember/component';
import { computed } from '@ember-decorators/object';

export default class TheComponent extends Component {
   styleNamespace: string;
   status: string;

   @computed('styleNamespace', 'status')
   get statusClass(this: CertificateCard) {
     return `${this.get('styleNamespace')}--${this.get('status')}`
   }
}
Run Code Online (Sandbox Code Playgroud)

与Ember 3.1,可以稳定启动灰烬RFC#281,你就可以通过降低进一步简化这个this.get对于任何不涉及财产代理.请注意,您还可以删除this类型声明.

import Component from '@ember/component';
import { computed } from '@ember-decorators/object';

export default class TheComponent extends Component {
  styleNamespace: string;
  status: string;

  @computed('styleNamespace', 'status')
  get statusClass() {
    return `${this.styleNamespace}--${this.status}`;
  }
}
Run Code Online (Sandbox Code Playgroud)

(顺便说一句:如果已知属性不是计算属性,而是例如在构造时传递到组件中的简单字符串,则可以在Ember 3.1之前执行此操作.)


关于对装饰器提议的未来和稳定性的任何可能的担忧:对规范的任何建议的改变都不会对我们在Ember.js中使用的装饰器的消费者产生影响.他们将需要实现者(例如,处理ember-decorators项目的团队)进行更改,但消费代码(即常规应用程序和插件)将不受影响.