Ember-cli-typescript: The 'this' context of type 'this' is not assignable to method's 'this' of type '...'

Created on 24 Mar 2018  路  9Comments  路  Source: typed-ember/ember-cli-typescript

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

bug core

Most helpful comment

Fixed in @types/ember@~3.0.0 (now published)

All 9 comments

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)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

chriskrycho picture chriskrycho  路  8Comments

mfeckie picture mfeckie  路  7Comments

chriskrycho picture chriskrycho  路  8Comments

boris-petrov picture boris-petrov  路  7Comments

jamesarosen picture jamesarosen  路  6Comments