Ember 3.13+ and TypeScript: Computed properties don't work as expected
See original GitHub issueHi all,
we are currently using Ember 3.12 with ember-cli-typescript
and would like to upgrade to Ember 3.14+, but as of Ember 3.13 wie experience problems with this upgrade.
In https://github.com/emberjs/ember.js/issues/18614, @pzuraq gave us a very helpful hint that the problem could be ember-cli-typescript
or TypeScript itself.
We hope that you can help us.
Please paste the output of ember -v
here
ember-cli: 3.13.2
node: 12.13.1
os: win32 x64
Please paste the output of tsc -v
here
Version 3.7.3
Please paste the version of ember-cli-typescript
and ember-cli-typescript-blueprints
here
ember-cli-typescript@3.1.2
ember-cli-typescript-blueprints@3.0.0
Please paste your tsconfig.json
and tslint.json
or eslint.json
(if applicable) below
My tsconfig.json
{ "compilerOptions": { "target": "es2017", "allowJs": true, "moduleResolution": "node", "allowSyntheticDefaultImports": true, "noImplicitAny": true, "noImplicitThis": true, "alwaysStrict": true, "strictNullChecks": true, "strictPropertyInitialization": true, "noFallthroughCasesInSwitch": true, "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noEmitOnError": false, "noEmit": true, "inlineSourceMap": true, "inlineSources": true, "baseUrl": ".", "module": "es6", "experimentalDecorators": true, "paths": { "test-model-reactivity/tests/*": [ "tests/*" ], "test-model-reactivity/*": [ "app/*" ], "*": [ "types/*" ] } }, "include": [ "app/**/*", "tests/**/*", "types/**/*" ] }
What are instructions we can follow to reproduce the issue?
ember new test-model-reactivity
ember install ember-cli-typescript
Reproduction Case
ember g route application
ember g controller application
Add the following lines
// routes/application.ts
import Route from "@ember/routing/route";
import RSVP from "rsvp";
export class Example {
constructor(public value: string) { }
}
export class ApplicationModel {
constructor(public example: Example) { }
}
export default class Application extends Route {
model(_params: {}, _transition: any): RSVP.Promise<ApplicationModel> {
return RSVP.resolve(new ApplicationModel(new Example("test")));
}
}
// controllers/application.ts
import Controller from "@ember/controller";
import {ApplicationModel} from "test-model-reactivity/routes/application";
import {action, computed, set} from "@ember/object";
export default class Application extends Controller {
model!: ApplicationModel;
@computed("model.example.value")
get value() {
return this.model.example.value;
}
@action
changeExampleValue() {
set(this.model.example, "value", String(Math.random()));
}
}
// DO NOT DELETE: this is how TypeScript knows how to look up your controllers.
declare module "@ember/controller" {
interface Registry {
"application": Application;
}
}
{{! templates/application.hbs }}
<button {{on "click" this.changeExampleValue}}>
{{this.value}}
</button>
Now about that bug. What did you expect to see?
The template should update after the button was clicked.
What happened instead?
The template is not updated because the computed property value
is not executed.
Hint
The JavaScript version of the example above works like expected, only the TypeScript version has this problems.
Issue Analytics
- State:
- Created 4 years ago
- Comments:8 (4 by maintainers)
Top Results From Across the Web
What is the proper way to write a computed property using ...
1 Answer 1 · I'm a little confused here, @chris-krycho. It seems that your version of the cp code and my version are...
Read more >Computed properties: What am I missing? - General
Hi,. The behavior of ember computed properties always suprises me and I would like to have a better understand of it. (I am...
Read more >Awesome Ember.js
ember -local-storage - The addon provides a storage for computed property that returns a proxy and persists the changes to localStorage or sessionStorage....
Read more >Moving from React to Ember 2020 : r/emberjs
Due to the Octane work (I guess) Ember has lost the capacity of two-way binding to older components' computed properties, and this was...
Read more >Computed Properties - ember-cli-typescript
Note that it is impossible for @computed to know whether the keys you pass to it are allowed or not. Migrating to Octane...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Yep, that’s a known issue which will have a release with the fix shortly.
I’ll make sure we cover this failure case more thoroughly in the updated docs, but this is in fact expected behavior (and doesn’t require changing the base types). The problem is what this transpiles to:
The resulting output per the spec is (basically):
TS has basically “overloaded” the meaning of a property declaration on a class like this, by making it where you declare the type as well. This is what you found in your inspection of the compiled output: even if the declaration is
bar: string
rather thanbar;
, it has the same output. The TypeScript team is aware of this issue, and in fact TypeScript 3.7 includes a newdeclare
syntax to support this exact use case. With that new syntax, you’d write it like this:I’m not sure what changed between 3.12 and 3.13; it’s possible an ordering difference around
setupController
and the instantiation of theController
was introduced in certain edge cases.ember-cli-typescript
and our compilation pipeline’s handling of this specific scenario haven’t changed in quite some time, so while it’s not impossible that we’re doing something wrong, I’d be much more suspicious of changes in the framework.cc. @rwjblue @pzuraq @chancancode – the only thing I can think of here that would be relevant in the 3.12→3.13 is the prep work that was done to support
@model
in 3.14?