Here is a sample model (with ember-decorators@next):
import Model from 'ember-data/model';
import { attr } from '@ember-decorators/data';
export default class MyModel extends Model {
@attr('number')
start: number;
@attr('date')
startTime: Date;
getStart() {
if (this.start) {
return this.start;
}
if (this.startTime) {
return this.startTime.getTime();
}
}
setStart(value) {
if (value instanceof Date) {
this.set('startTime', value);
} else {
this.set('start', value);
}
}
}
The lines with this.set() are moaned by vscode. Though doing setStart(this: MyModel, value) will "fix" the warning, though nobody wants to do this 馃榿. My tsconfig.json:
{
"compilerOptions": {
"target": "es2017",
"allowJs": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"noImplicitThis": true,
"noEmitOnError": false,
"noEmit": true,
"inlineSourceMap": true,
"inlineSources": true,
"baseUrl": ".",
"module": "es6",
"traceResolution": false,
"paths": {
"my-app-client/tests/*": [
"tests/*"
],
"my-app/*": [
"app/*"
],
"*": [
"types/*"
]
}
},
"include": [
"app",
"tests",
"types"
]
}
ember-cli-typescript: v1.2.1
Even funnier, adding a private property will prevent the this: MyModel workaround to actually stop reporting an error. Example:
import Model from 'ember-data/model';
import { attr } from '@ember-decorators/data';
export default class MyModel extends Model {
private myPrivateProperty: any = null;
@attr('number')
start: number;
@attr('date')
startTime: Date;
getStart() {
if (this.start) {
return this.start;
}
if (this.startTime) {
return this.startTime.getTime();
}
}
setStart(this: MyModel, value) {
if (value instanceof Date) {
this.set('startTime', value);
} else {
this.set('start', value);
}
}
}
the warning is still present.
Thanks for the reproduction. I pared down to something more minimal:
import Ember from 'ember';
import { set } from '@ember/object';
class MyModel extends Ember.Object {
start: number;
setStart(value: number) {
/*
Error:(16, 5) TS2684: The 'this' context of type 'this' is not assignable to method's 'this' of type 'ComputedProperties<{ start: any; setStart: any; get: any; getProperties: any; set: any; setProper...'.
Type 'MyModel' is not assignable to type 'ComputedProperties<{ start: any; setStart: any; get: any; getProperties: any; set: any; setProper...'.
Types of property 'notifyPropertyChange' are incompatible.
Type '(keyName: string) => MyModel' is not assignable to type '((keyName: string) => this) | ComputedProperty<(keyName: string) => this> | ComputedProperty<(key...'.
Type '(keyName: string) => MyModel' is not assignable to type 'ComputedProperty<(keyName: string) => this>'.
Property 'volatile' is missing in type '(keyName: string) => MyModel'.
*/
this.set('start', value);
// these both work:
this.start = value;
set(this, 'start', value);
}
}
The setStart(this: MyModel, ... workaround does work.
The problem seems to be the return type on this method:
interface Observable {
notifyPropertyChange(keyName: string): this;
}
Changing it to return Observable, while slightly less correct, will fix this.
But when I add a private property, I get an error again:
import Ember from 'ember';
import DS from 'ember-data';
import { set } from '@ember/object';
class MyModel extends DS.Model.extend(Ember.Evented) {
start: number;
private myPrivateProperty: any = null;
setStart(value: number) {
/*
Error:(16, 5) TS2684: The 'this' context of type 'this' is not assignable to method's 'this' of type 'ComputedProperties<{ start: any; myPrivateProperty: any; setStart: any; on: any; one: any; trigge...'.
Type 'MyModel' is not assignable to type 'ComputedProperties<{ start: any; myPrivateProperty: any; setStart: any; on: any; one: any; trigge...'.
Property 'myPrivateProperty' is private in type 'MyModel' but not in type 'ComputedProperties<{ start: any; myPrivateProperty: any; setStart: any; on: any; one: any; trigge...'.
*/
this.set('start', value);
// these both work:
this.start = value;
set(this, 'start', value);
}
}
It would be nice to find a proper fix which allows private properties
@dwickern I've never been able to figure out exactly where in the chain private breaks, but from what I recall looking at the error messages, I think it's something related to our use of Fix<T>. 馃槙
Faced with the same issue today after I declared a private property.
Am running into this as well, private properties cause tricky type errors. Is this seen as a bug that will be fixed? Or are we recommending using set() instead?
I think with typescript 2.9 this issue was gone for me. Do write your code as cleanly as it should look like. If TS has something to say about wrong typings, then it even might be TS who is wrong... like the message above... in that case, stick to your code and ignore TS message
Am on TypeScript 2.9 currently - for now I'm using global set() whenever this pops up
This fix has been merged, and should be available in the upcoming ~3.0.0 release of @types/ember. TypeScript >= 2.8 is required in order to use those types
Fixed in @types/ember@~3.0.0 (now published)
Most helpful comment
Fixed in
@types/ember@~3.0.0(now published)