Hi
Loving working in Angular, but pretty sure that as of Angular 12 with full support in Ionic (not yet there), we’ll be seeing a truckload of error messages here in this forum related to the strictness.
https://blog.angular.io/with-best-practices-from-the-start-d64881a16de8
Pretty sure we’ll need some sort of blog or suggestions. Or maybe, the ionic cli needs to give some support?
I’ve worked with some projects in Angular’s “strict mode”, and have employed noImplicitAny
, strictNullChecks
, and strictPropertyInitialization
since they became initially available. There may be some complaining about mountains of error messages if one starts retrofitting these settings, but I actually don’t think it’ll be very disruptive for new projects. The error messages are generally very clear and specific.
In fact, I think people who enable these settings in tsconfig.json
will be able to independently avoid many bugs that would otherwise be reported here as mysterious behavior. It’s much harder to make race conditions, for one.
So, I have
"strictPropertyInitialization": true,
"strictNullChecks": true,
And for instance I have
@ViewChild('slides', { static: true }) slides: IonSlides;
Which I reckon I have to rephrase to:
@ViewChild('slides', { static: true }) slides: IonSlides|undefined=undefined;
Which imho seems doable (if that is proper thing to do).
But then I have to do something about
await this.slides.slideNext();
Because TS tells me that this.slides can be undefined.
So, I have to build checks on undefined as solution?
Maybe I shouldnt be migrating existing projects, and indeed for new projects this could work.
I don’t set static
on ViewChild
. In fact, the static
flag on ViewChild
tends to paper over just this exact problem. Instead of relying on it, I prefer to use ngAfterViewInit
to perform setup activities that rely on ViewChild
being populated. If you do that, it doesn’t matter what the setting of the static
field is, and you can just leave it out. So that declaration can be simplified considerably to:
@ViewChild("slides"} slides?: IonSlides;
That ?
effectively desugars to | undefined = undefined
.
You have several options for the other issue. What I tend to prefer if there are going to be a bunch of references to the lazily-instantiated property is a lexical alias:
if (!this.slides) {
throw new Error("failed to capture slides element");
}
let slides = this.slides;
await slides.slideNext();
await slides.slideUp();
await slides.slideDown();
await slides.shakeItAllAbout();
TS should “know” that the lexical slides
variable is an IonSlides
.
For one-offs, there is the non-null assertion operator (although I don’t believe the default tslint
rules consider it kosher): await this.slides!.slideNext()
.