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>
|
||||
|
||||
### 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
|
||||
|
||||
|
|
Loading…
Reference in New Issue