javascript / intermediate
Snippet
Enforcing Model Type Safety with Generic Base Components
Abstract directive classes in Angular allow shared state, common inputs/outputs, and lifecycle methods to be inherited across multiple editor components. Applying generic type constraints ensures that inheriting components strictly adhere to model requirements while preserving compile-time type checking.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import { Directive, EventEmitter, Input, Output } from '@angular/core';export interface BaseEntity {id: string | number;updatedAt: Date;}@Directive()export abstract class BaseEditorComponent<T extends BaseEntity> {@Input({ required: true }) entity!: T;@Output() save = new EventEmitter<T>();@Output() cancel = new EventEmitter<void>();protected isDirty = false;abstract validateEntity(model: T): boolean;public handleSave(): void {if (this.validateEntity(this.entity)) {this.isDirty = false;this.save.emit(this.entity);}}public handleCancel(): void {this.isDirty = false;this.cancel.emit();}}
angular
Breakdown
1
@Directive()
Applies Angular's Directive decorator to enable dependency injection and property bindings on an abstract base class.
2
export abstract class BaseEditorComponent<T extends BaseEntity> {
Defines an abstract class parameterized by a generic type T constrained to BaseEntity implementations.
3
@Input({ required: true }) entity!: T;
Enforces a required strongly-typed input representing the entity model being edited.
4
abstract validateEntity(model: T): boolean;
Forces concrete child subclasses to implement domain-specific validation logic.
5
if (this.validateEntity(this.entity)) {
Executes polymorphism: delegates validation to the derived class before emitting save events.