Vscode-ng-language-service: typescript 2.7 strict property initialization breaks type inference

Created on 3 Feb 2018  路  6Comments  路  Source: angular/vscode-ng-language-service

I upgraded to typescript 2.7 with the new strict property initialization feature: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html

This means it will warn if mandatory properties are not initialized in the constructor. This is quite common with mandatory component inputs. They are not set from the constructor, so TS will complain about:

@Component(...)
export class AppComponent {
  @Input() foo: Foo;
}

since foo is never initialized. You can fix this with a manual assertion that the property will be set during initialization (notice the exclamation mark in the foo property declaration):

@Component(...)
export class AppComponent {
  @Input() foo!: Foo;
}

However, once you do this the type inference of angular language service in vs code breaks with an error [Angular] Identifier 'name' is not defined. '<anonymous>' does not contain such a member:
image

For a reproducing repo see https://github.com/wvanderdeijl/angular-strict-prop-init

Most helpful comment

The good news is that TS 2.7 is supported by the just released version 0.1.10. The bad news is I'm still seeing this error and it might be related to this issue. The object being referenced has a key index signature, rather than a definite-assignment assertion, but the symptoms are the same. If it's the same issue, c.f. #149 and #126.

All 6 comments

Unfortunately TS 2.7 is not supported by Angular. Since it is now officially released, Angular should add support soon.

@hccampos are there any workarounds that you know of? Getting the same non-sense in my HTML.

@wvanderdeijl in the meantime use "strictPropertyInitialization": false,. I'm using ts 2.7 as well, not just because --watch is faster but also it fixes relative auto imports in vscode.

In the long term, I don't see any reasonable way, how angular will be able to solve this. I guess it's just best to always provide default values for your Inputs without having to use definite assignment assertion modifier !.

Or to be programatically correct turn the flag on and do following:

@Component({
  selector: 'app-test',
  template: '<div>{{ foo?.name }}</div>'
})
export class AppComponent {
  // foo can be undefined
  // both TS 2.7 and language service will compile correctly
  @Input() foo?: Foo;
  // or you can write @Input() foo: Foo | void = undefined; which is the same as above, just more explicit
}

Why is this ok? well angular compiler hasn't any capabilities how to make props really required,
so even if you won't make the Input "required" in the class, you can still write <app-test><app-test> and compiler will throw no errors at all, even if the property Input is not optional 馃憥

The good news is that TS 2.7 is supported by the just released version 0.1.10. The bad news is I'm still seeing this error and it might be related to this issue. The object being referenced has a key index signature, rather than a definite-assignment assertion, but the symptoms are the same. If it's the same issue, c.f. #149 and #126.

Closing this, since Angular now uses TypeScript 3.6.
Please upgrade to the latest version, and let us know if you still run into this problem. Thank you!

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings