I am trying to define a reusable store feature (withPaginatedData
) that has a specific internal data structure and expects only one method to load data (loadData
) in a fixed format.
This has worked well so far. However, when I extend this store with a property via withState(), numerous type errors occur.
Types of property methods are incompatible. Property loadData is missing in type MethodsDictionary but required in type { loadData: (options: LoadDataOptions, filters?: undefined) => Observable; }
it seems that the defined method loadData
is not recognized anymore as soon as there is another state defined.
import { signalStore, signalStoreFeature, type, withMethods, withState } from '@ngrx/signals';
import { Observable, of } from 'rxjs';
interface LoadDataOptions {
page: number;
size: number;
}
interface MyEntity {
id: string;
}
export function withPaginatedData<Entity, Filters extends object | undefined = undefined>() {
return signalStoreFeature(
{
methods: {
loadData: type<(options: LoadDataOptions, filters?: Filters) => Observable<Entity>>(),
},
},
withMethods((store) => ({
foo: () => {
store.loadData({ page: 1, size: 100 });
},
})),
// more happening here
);
}
export const MyStore = signalStore(
{ providedIn: 'root' },
withState({ selectedId: '' }),
withMethods((state) => ({
loadData: (options: LoadDataOptions) => {
console.log(options, state.selectedId());
const demoData: MyEntity = { id: '1' };
return of(demoData);
},
})),
withPaginatedData<MyEntity, undefined>(),
);
Or see it on Stackblitz
If you comment out the line withState({ selectedId: '' }),
(as well as the console.log) the type is fine.
I am trying to define a reusable store feature (withPaginatedData
) that has a specific internal data structure and expects only one method to load data (loadData
) in a fixed format.
This has worked well so far. However, when I extend this store with a property via withState(), numerous type errors occur.
Types of property methods are incompatible. Property loadData is missing in type MethodsDictionary but required in type { loadData: (options: LoadDataOptions, filters?: undefined) => Observable; }
it seems that the defined method loadData
is not recognized anymore as soon as there is another state defined.
import { signalStore, signalStoreFeature, type, withMethods, withState } from '@ngrx/signals';
import { Observable, of } from 'rxjs';
interface LoadDataOptions {
page: number;
size: number;
}
interface MyEntity {
id: string;
}
export function withPaginatedData<Entity, Filters extends object | undefined = undefined>() {
return signalStoreFeature(
{
methods: {
loadData: type<(options: LoadDataOptions, filters?: Filters) => Observable<Entity>>(),
},
},
withMethods((store) => ({
foo: () => {
store.loadData({ page: 1, size: 100 });
},
})),
// more happening here
);
}
export const MyStore = signalStore(
{ providedIn: 'root' },
withState({ selectedId: '' }),
withMethods((state) => ({
loadData: (options: LoadDataOptions) => {
console.log(options, state.selectedId());
const demoData: MyEntity = { id: '1' };
return of(demoData);
},
})),
withPaginatedData<MyEntity, undefined>(),
);
Or see it on Stackblitz
If you comment out the line withState({ selectedId: '' }),
(as well as the console.log) the type is fine.
2 Answers
Reset to default 1 +100You don't need to specify the generic types when calling withPaginatedData<MyEntity, undefined>()
. Removing the generic parameters resolves the compilation error, allowing you to simply use withPaginatedData()
.
This issue appears to be related to a type conflict between the defined state in singleStore and the inferred return type from signalStoreFeature.
Similar issue is described in ngrx docs
Stackblitz, if you need it.
You should declare the return type of withPaginatedData function. Otherwise, it is not be recognized by MyStore