Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

The 'this' context of type 'this' is not assignable to method's 'this' of type '...' #176

Closed
gossi opened this issue Mar 24, 2018 · 9 comments
Labels
bug types:core Something is wrong with the Ember type definitions

Comments

@gossi
Copy link

gossi commented Mar 24, 2018

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

@gossi
Copy link
Author

gossi commented Mar 24, 2018

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.

@dwickern
Copy link
Contributor

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

@chriskrycho
Copy link
Member

@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>. 😕

@iAchilles
Copy link

Faced with the same issue today after I declared a private property.

@ghost
Copy link

ghost commented Jul 21, 2018

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?

@gossi
Copy link
Author

gossi commented Jul 21, 2018

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

@ghost
Copy link

ghost commented Jul 21, 2018

Am on TypeScript 2.9 currently - for now I'm using global set() whenever this pops up

@mike-north
Copy link
Contributor

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

@mike-north
Copy link
Contributor

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

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
bug types:core Something is wrong with the Ember type definitions
Projects
None yet
Development

No branches or pull requests

5 participants