How to get the right type for a callback that acts on a signal store's custom-feature data? #4543
-
Simplified ScenarioSay you have a signal store that has 2 custom features registered, both of which add state and methods with generic names. // example.store.ts
export type ExampleStoreType = InstanceType<typeof ExampleStoreType>;
export const ExampleStore = signalStore(
{ providedIn: 'root' },
withExample('example'),
withExample('other'),
); // withExample.ts
import {
signalStore,
signalStoreFeature,
SignalStoreFeature,
withMethods,
withState,
} from '@ngrx/signals';
export type ExampleState<Prop extends string> = {
[K in Prop as `${K}Field`]: string;
};
export type ExampleMethods<Prop extends string> = {
[K in Prop as `do${K}`]: () => void;
};
export type EmptyFeature = {
state: {};
signals: {};
methods: {};
computed: {};
};
export type FilledFeature<Prop extends string> = {
state: ExampleState<Prop>;
computed: {};
methods: ExampleMethods<Prop>;
};
export function withExample<Prop extends string>(
name: Prop,
): SignalStoreFeature<EmptyFeature, FilledFeature<Prop>> {
return signalStoreFeature(
withState<ExampleState<Prop>>({
[`${name}Field`]: 'foo',
} as ExampleState<Prop>),
withMethods((store) => {
return {
[`do${name}`]: () => {
// Some logic
},
} as ExampleMethods<Prop>;
}),
) as SignalStoreFeature<EmptyFeature, FilledFeature<Prop>>;
} The store this generates has these fields: {
// from withExample('example')
exampleField: Signal<string>,
doexample: () => void,
// from withExample('other')
otherField: Signal<string>,
doother: () => void
} The ProblemNow say this store has a special case where if // withExample.ts
export function withExample<Store, Prop extends string>(
name: Prop,
onSuccess?: (store: Store) => void
): SignalStoreFeature<EmptyFeature, FilledFeature<Prop>> {
... But how do you get the type of // example.store.ts
export type ExampleStoreType = InstanceType<typeof ExampleStoreType>;
export const ExampleStore = signalStore(
{ providedIn: 'root' },
withExample(('example', (store: ???) => ),
withExample('other'),
); I can't use
So how else can I get a type for the In practice I'm encountering this with my own custom signal store features that execute HTTP requests, store the result in a state-field and keep track of the request state (failed, loading, success, init). There you have scenarios where one request may delete an entry from a list and then you want to update that list in your store to remove said entry. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 8 replies
-
@PhilippMDoerner, thanks for writing it that detailed. Would it be possible to set up your example on https://stackblitz.com/github/ngrx/signal-store-starter? It would make it much easier. |
Beta Was this translation helpful? Give feedback.
@PhilippMDoerner, you do it the other way around. You define the callback as private method, and the extension uses it then:
https://stackblitz.com/edit/github-kvtghf-9o34rq?file=src%2FwithExample.ts