I’m setting up a set of generic classes to eliminate boylarplate code with ordinary forms and tables. The classes are as follows.
export interface BaseEntity {
id: number;
}
to mark subject entities.
export abstract class BaseEntityService<Entity extends BaseEntity> {...}
data service, to retrieve data from the backend. And a building block for signal store, to mediate between the data service and the component.
export function baseEntityStore<Entity extends BaseEntity, DataService extends BaseEntityService<Entity>>(dataServiceType: Type<DataService>) {
return signalStoreFeature(...)
Finally I want to have abstract components to accomplish all ordinary tasks like loading data, show errors etc. while using forms or tables.
@Component({ template: '' })
export abstract class BaseEntityComponent<Entity extends BaseEntity> implements OnInit {
protected entity: Entity | undefined;
protected formBuilder = inject(FormBuilder);
protected formGroup!: FormGroup;
protected store;
protected constructor(repository: Type<BaseEntityService<Entity>>) {
this.store = inject( baseEntityStore( repository ));
this.store.loadAll();
this.registerEffects();
}
...
}
Here I’d like to use the functionality of the baseEntityStore() to accomplish repeating tasks. And exactly here is the painpoint: How can I refer to the baseEntityStore function’s type?
Of course later on it will exist Entity specific DataService, signalStore and Component. The problem is that I can’t move up functionality to the BaseEntityComponent because it doesn’t know the baseEntityStore signature.
A more elaborated example is available at https://stackblitz.com/edit/stackblitz-starters-qymttb?file=package.json