We are using the following Config
class to configure our component.
export type Language = 'javascript' | 'typescript' | 'elixir';
export class Config {
name: string = 'RxJS';
responsive: boolean = true;
language: Language = 'typescript';
}
We want to configure it using an @Input()
property like this:
[config]="{ name: 'Firefly Semantics Slice',
language: 'typescript',
responsive: true }"
Approach
In order to demo this we will alter the Stackblitz hello component slightly adding the config @Input
property.
export class Config {
name: string = 'RxJS';
responsive: boolean = true;
language: Language = 'typescript';
}
@Component({
selector: 'hello',
template: `<h1>Hello {{config.name}}!</h1>`,
styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements AfterViewInit {
@Input() config: Config;
ngAfterViewInit() {
console.log(this.config);
}
}
Now we can configure instances of the HelloComponent
component like this.
<hello
[config]="{
name: 'Firefly Semantics Slice',
language: 'typescript',
responsive: true
}"
></hello>
<hello
[config]="{ name: name, language: 'typescript', responsive: false }"
></hello>
Note that in the last hello
declaration within the app.component.html
template we are interpolating the name
property directly into the config object.
<hello [config]="{ name: name, language: 'typescript', responsive: false }">
</hello>
Note that if we leave off a property like name
we will get an error.
Property 'name' is missing in type '{ language: "typescript"; responsive: true; }' but required in type 'Config'
We can make properties optional by using a Partial
and a setter like this (Note that we have moved @Input
above set
).
_config: Config = new Config();
@Input()
set config(c: Partial<Config>) {
this._config = Object.assign(this._config, c);
}
get config() {
return this._config;
}
Demo
With Partial
.