docs: add a style recommendation for initializing inputs (#40698)
This practice is to better align with `strictPropertyInitialization` which is coming by default with strict mode in v12. PR Close #40698
This commit is contained in:
parent
980f6a4958
commit
72a00dcc6b
|
@ -0,0 +1,7 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'sg-app',
|
||||||
|
template: '<toh-hero-list></toh-hero-list>'
|
||||||
|
})
|
||||||
|
export class AppComponent { }
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { RouterModule } from '@angular/router';
|
||||||
|
|
||||||
|
import { AppComponent } from './app.component';
|
||||||
|
import { HeroComponent, HeroListComponent } from './heroes';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
RouterModule.forChild([{ path: '05-18', component: AppComponent }])
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
HeroComponent,
|
||||||
|
HeroListComponent
|
||||||
|
],
|
||||||
|
exports: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule {}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
import { Hero } from '../shared/hero.model';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'toh-hero-list',
|
||||||
|
template: `
|
||||||
|
<section>
|
||||||
|
Our list of heroes:
|
||||||
|
<toh-hero *ngFor="let hero of heroes">
|
||||||
|
</toh-hero>
|
||||||
|
Total powers: {{totalPowers}}<br>
|
||||||
|
Average power: {{avgPower}}
|
||||||
|
</section>
|
||||||
|
`
|
||||||
|
})
|
||||||
|
export class HeroListComponent {
|
||||||
|
heroes: Hero[] = [];
|
||||||
|
totalPowers = 1;
|
||||||
|
|
||||||
|
get avgPower() {
|
||||||
|
return this.totalPowers / this.heroes.length;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './hero-list.component';
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
// #docregion example
|
||||||
|
@Component({
|
||||||
|
selector: 'toh-hero',
|
||||||
|
template: `...`
|
||||||
|
})
|
||||||
|
export class HeroComponent {
|
||||||
|
// The exclamation mark suppresses errors that a property is
|
||||||
|
// not initialized.
|
||||||
|
// Ignoring this enforcement can prevent the type checker
|
||||||
|
// from finding potential issues.
|
||||||
|
@Input() id!: string;
|
||||||
|
}
|
||||||
|
// #enddocregion example
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
// #docregion example
|
||||||
|
@Component({
|
||||||
|
selector: 'toh-hero',
|
||||||
|
template: `...`
|
||||||
|
})
|
||||||
|
export class HeroComponent {
|
||||||
|
@Input() id?: string;
|
||||||
|
|
||||||
|
process() {
|
||||||
|
if (this.id) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// #enddocregion example
|
|
@ -0,0 +1,11 @@
|
||||||
|
import { Component, Input } from '@angular/core';
|
||||||
|
|
||||||
|
// #docregion example
|
||||||
|
@Component({
|
||||||
|
selector: 'toh-hero',
|
||||||
|
template: `...`
|
||||||
|
})
|
||||||
|
export class HeroComponent {
|
||||||
|
@Input() id = 'default_id';
|
||||||
|
}
|
||||||
|
// #enddocregion example
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './hero.component';
|
|
@ -0,0 +1,3 @@
|
||||||
|
export * from './hero';
|
||||||
|
export * from './hero-list';
|
||||||
|
export * from './shared';
|
|
@ -0,0 +1,4 @@
|
||||||
|
export interface Hero {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
export * from './hero.model';
|
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './heroes';
|
||||||
|
export * from './app.component';
|
|
@ -3381,6 +3381,23 @@ helps instantly identify which members of the component serve which purpose.
|
||||||
|
|
||||||
<a href="#toc">Back to top</a>
|
<a href="#toc">Back to top</a>
|
||||||
|
|
||||||
|
### Initialize inputs
|
||||||
|
|
||||||
|
#### Style 05-18
|
||||||
|
|
||||||
|
TypeScript's `--strictPropertyInitialization` compiler option ensures that a class initializes its properties during construction. When enabled, this option causes the TypeScript compiler to report an error if the class does not set a value to any property that is not explicitly marked as optional.
|
||||||
|
|
||||||
|
By design, Angular treats all `@Input` properties as optional. When possible, you should satisfy `--strictPropertyInitialization` by providing a default value.
|
||||||
|
|
||||||
|
<code-example path="styleguide/src/05-18/app/heroes/hero/hero.component.ts" region="example" header="app/heroes/hero/hero.component.ts"></code-example>
|
||||||
|
|
||||||
|
If the property is hard to construct a default value for, use `?` to explicitly mark the property as optional.
|
||||||
|
|
||||||
|
<code-example path="styleguide/src/05-18/app/heroes/hero/hero.component.optional.ts" region="example" header="app/heroes/hero/hero.component.ts"></code-example>
|
||||||
|
|
||||||
|
You may want to have a required `@Input` field, meaning all your component users are required to pass that attribute. In such cases, use a default value. Just suppressing the TypeScript error with `!` is insufficient and should be avoided because it will prevent the type checker ensure the input value is provided.
|
||||||
|
|
||||||
|
<code-example path="styleguide/src/05-18/app/heroes/hero/hero.component.avoid.ts" region="example" header="app/heroes/hero/hero.component.ts"></code-example>
|
||||||
|
|
||||||
## Directives
|
## Directives
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue