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

时间:2018-03-16 00:46:31

标签: typescript ember.js

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

   @computed('styleNamespace', 'status')
   statusClass(componentClassName: string, status: string): string {
     return `${componentClassName}--${status}`
   }

但是我从来没有能够正确地通过TypeScript检查。在回顾了Chris Krycho的Emberconf training materials之后,似乎“正确”的方式如下:

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

这是对的吗?我似乎错过了一些东西,但因为我仍然遇到这样的错误:

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

1 个答案:

答案 0 :(得分:6)

要使装饰器与Ember.js中的TypeScript一起使用,您至少需要使用ember-decorators 2.0.0(在此答案时可用2.0.0-beta.2)并设置{{1您"experimentalDecorators": true的{​​{1}}部分。

然后,对于3.1之前的所有Ember版本,你都会像这样编写计算机(如第二个例子中所示,但是对于后来偶然发现的其他人来说,写得更完整)。请注意,我们不需要getter的返回类型,因为它可以通过TypeScript正确推断(与经典的Ember计算属性回调不同,其中返回类型 需要显式)。

"compilerOptions"

从稳定Ember RFC #281的Ember 3.1开始,您可以通过删除{em>任何任何属性tsconfig.json来进一步简化此操作3}}。请注意,您还可以删除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')}` } } 类型声明。

this.get

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

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