ember-cli-typescript icon indicating copy to clipboard operation
ember-cli-typescript copied to clipboard

Type errors on computed properties when upgrading to TypeScript 3.7

Open richard-viney opened this issue 5 years ago • 7 comments

Which package(s) does this problem pertain to?

  • @types/ember__object

Repro steps

The following code reports no typing errors in TypeScript 3.6.3, but gives errors in TypeScript 3.7.2.

declare class MyClass {
  isNew: Ember.ComputedProperty<boolean>
}

function foo(a: MyClass): boolean {
  // TS2322: Type 'ComputedProperty<boolean, boolean>' is not assignable to
  // type 'boolean'.
  return a.isNew
}

function bar(a: MyClass): void {
  // TS2774: This condition will always return true since the function is always
  // defined. Did you mean to call it instead?
  if (a.isNew) {
    // ...
  }
}

The two errors above are likely caused by the same underlying issue. The expected result is no errors upgrading from TS 3.6 to 3.7. This issue was noticed due to new type errors when using the DS.Model.isNew property on instances of Ember Data models.

The workaround appears to be to use get() instead of direct property access.

Thanks.

richard-viney avatar Nov 26 '19 04:11 richard-viney

Thank you for reporting this!

This appears (at very first blush and without having investigated at all) to be a case where TS 3.7 is actually being more strictly correct. Types defined as ComputedProperty<T> or a descendant thereof do require the use of get to unwrap them.

However, this likely points to an issue with our Ember Data types, in that most things in Ember Data (everything that isn't an async relationship, basically) should Just Work™ with normal property access. We appreciate the report and will hopefully get a fix in place soon!

chriskrycho avatar Dec 06 '19 04:12 chriskrycho

I am also seeing a similar issue. Here is the code for reference:

const thisIsABool = this.someModel.isNew;
if (thisIsABool) {
  return false;
} 

image

Alonski avatar Dec 16 '19 09:12 Alonski

What was the actual code that caused this? I assume it wasn’t a local declaration of a ComoutedProperty? 😂

chriskrycho avatar Dec 16 '19 12:12 chriskrycho

Is there any update on this? The interaction between the ember/no-get lint rule and the need to call get to "unwrap" these computed properties is frustrating.

nragaz avatar Jan 07 '21 19:01 nragaz

Hadn’t been any motion, but is likely to be a lot of motion in related spaces starting in about two weeks: we’ve kicked off a “strike team” with the aim of getting official TS support in Ember and things like this will absolutely get addressed as part of that (though the result will be months of effort to get there).

chriskrycho avatar Jan 08 '21 02:01 chriskrycho

Does anyone have a workaround for this that doesn't involve disabling the ember/no-get lint rule and converting everything to get('isNew')?

drewpereli avatar Sep 22 '21 06:09 drewpereli

In general, the workaround is: switch to native classes and use native getters and setters. The problem just goes away if you are not using classic classes with TypeScript. The main exception is Ember Data types, and those haven’t been updated to handle this, but could and should to go with the 4.0 release. I’d be happy to describe how to do that in detail if someone wants to pick up the work!

chriskrycho avatar Sep 22 '21 16:09 chriskrycho