ember.js - ¿Cuál es la manera adecuada de escribir una propiedad computada usando TypeScript y Ember?
Tengo una aplicación relativamente pequeña en Ember/TypeScript en la que he estado trabajando durante unos seis meses. Solía definir propiedades computadas de la siguiente manera:
@computed('styleNamespace', 'status')
statusClass(componentClassName: string, status: string): string {
return `${componentClassName}--${status}`
}
Pero nunca he podido lograr que esto pase correctamente la verificación de TypeScript. Después de revisar los materiales de entrenamiento de Emberconf de Chris Krycho, parece que la manera "correcta" de hacer esto es la siguiente:
@computed('styleNamespace', 'status')
get statusClass(this: CertificateCard): string {
return `${this.get('styleNamespace')}--${this.get('status')}`
}
¿Esto es correcto? Sin embargo, parece que me falta algo porque todavía estoy obteniendo errores como este:
Error: Assertion Failed: Attempted to apply @computed to statusClass,
but it is not a native accessor function.
Try converting it to `get statusClass()`
Respuesta #1
Para que los decoradores funcionen con TypeScript en Ember.js, necesitarás usar al menos ember-decorators 2.0.0 (disponible en el momento de esta respuesta como 2.0.0-beta.2) y establecer "experimentalDecorators": true en la sección "compilerOptions" de tu tsconfig.json.
Entonces, para todas las versiones de Ember anteriores a la 3.1, escribirás los computados de esta manera (como en tu segundo ejemplo, pero escrito de manera más completa para cualquiera que se encuentre con esto más adelante). Ten en cuenta que no necesitamos el tipo de retorno para el getter, ya que puede ser inferido correctamente por TypeScript (a diferencia de los callbacks de propiedades computadas clásicas de Ember, donde el tipo de retorno sí debía ser explícito).
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.get('styleNamespace')}--${this.get('status')}`
}
}
A partir de Ember 3.1, que estabiliza Ember RFC #281, podrás simplificar esto aún más eliminando this.get para cualquier propiedad que no implique Proxies. Ten en cuenta que también podrás eliminar las declaraciones de tipo this entonces.
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}`;
}
}
(A modo de aparte: si se sabe que las propiedades no son propiedades calculadas, sino, por ejemplo, cadenas simples pasadas al componente en el momento de la construcción, se puede hacer esto incluso antes de Ember 3.1.)
Con respecto a cualquier posible preocupación sobre el futuro y la estabilidad de la propuesta de decoradores: ningún cambio propuesto en la especificación tendrá un impacto en los consumidores de los decoradores que estamos usando en Ember.js. Requerirán que los implementadores (por ejemplo, el equipo que trabaja en el proyecto ember-decorators) hagan cambios, pero el código consumidor (es decir, en aplicaciones y complementos regulares) no se verá afectado.
