Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow generics in ngrx signals withEntites #4339

Closed
2 tasks
MeMeMax opened this issue May 14, 2024 · 2 comments
Closed
2 tasks

Allow generics in ngrx signals withEntites #4339

MeMeMax opened this issue May 14, 2024 · 2 comments

Comments

@MeMeMax
Copy link

MeMeMax commented May 14, 2024

Which @ngrx/* package(s) are relevant/related to the feature request?

signals

Information

I would like to store objects with different characteristics in the entity management.

Imagine you have a class "Controls" and several subclasses like "Button", "InputField", "OutputField", ....
They have common fields like "id", "isVisible" and also specific fields like "placeholder" for the "InputField".

With the current Definitions I can't achieve this in a typesafe way because withEntities doesn't allow generics. If I could pass a generic there and define which Type it is at component level this would work.

I think of something like this:
export const ControlsStore = signalStore(withEntities<T>());

In a potential Button Component I would use it like this:
controlsStore = inject(ControlsStore<ButtonControl>);

Describe any alternatives/workarounds you're currently using

Currently I am typing it like this:

export type Control<T> = T & {
  id: number;
  visible: boolean;
};

export interface ButtonControl {
  displayText: string;
}

export interface InputControl {
  placeholder: string;
}

export const ControlsStore = signalStore(withEntities<Control<any>>());

And using it in the ButtonComponent like this:

export class ButtonComponent {
  controlsStore = inject(ControlsStore);

  ngOnInit() {
    patchState(this.controlsStore, addEntity<Control<ButtonControl>>({ id: 1, visible: true, displayText: 'test' }));
  }
}

I would be willing to submit a PR to fix this issue

  • Yes
  • No
@markostanimirovic
Copy link
Member

I think of something like this:
export const ControlsStore = signalStore(withEntities<T>());

This is not the way how generics in TypeScript work - you cannot define a generic at the variable level. However, you can create a SignalStore factory function in the following way:

import { signalStore } from '@ngrx/signals';
import { withEntities } from '@ngrx/signals/entities';

export type Control<T> = T & {
  id: number;
  visible: boolean;
};

export interface ButtonControl {
  displayText: string;
}

export interface InputControl {
  placeholder: string;
}

// 👇
function createControlStore<T>() {
  return signalStore(withEntities<Control<T>>());
}

const ButtonStore = createControlStore<ButtonControl>();
const InputStore = createControlStore<InputControl>();

We use GitHub issues for bug reports and feature requests. For questions, you can use GitHub Discussions, Stackoverflow, or the official NgRx Discord server: https://discord.gg/ngrx

@markostanimirovic markostanimirovic closed this as not planned Won't fix, can't repro, duplicate, stale May 16, 2024
@MeMeMax
Copy link
Author

MeMeMax commented May 17, 2024

Thanks for your response. Unfortunately a factory function won´t help since I (and usually everyone using a signalStore) need a singleton across the application.

I know this doesn't work
export const ControlsStore = signalStore(withEntities<T>());
I just wanted to emphazise that I need something to make it generic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants