Skip to content

Commit

Permalink
fix(signals): patch state methods do not correctly resolve generic co…
Browse files Browse the repository at this point in the history
…llection names withEntities

Ensures type-safety of named entity collections with patchState helpers

fixes ngrx#4638
  • Loading branch information
ivashikhmin committed Dec 29, 2024
1 parent 34d18af commit 4f7181f
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
36 changes: 36 additions & 0 deletions modules/signals/entities/spec/types/models.types.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { expecter } from 'ts-snippet';
import { compilerOptions } from './helpers';

describe('models', () => {
const expectSnippet = expecter(
(code) => `
import { patchState, signalStore, type, withMethods } from '@ngrx/signals';
import { addEntity, entityConfig, withEntities } from '@ngrx/signals/entities';
type User = { id: number; name: string };
${code}
`,
compilerOptions()
);

it('succeeds when entity collection name is passed as the type parameter', () => {
const snippet = `
const storeFactory = <Collection extends string>(
collection: Collection
) => {
const Store = signalStore(
withEntities({ entity: type<User>(), collection: collection }),
withMethods((store) => ({
addUsers(user: User): void {
patchState(store, addEntity(user, { collection: collection }));
},
}))
);
return new Store();
};
`;

expectSnippet(snippet).toSucceed();
});
});
11 changes: 8 additions & 3 deletions modules/signals/entities/src/models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Signal } from '@angular/core';
import { Prettify } from '@ngrx/signals';

export type EntityId = string | number;

Expand All @@ -9,9 +10,13 @@ export type EntityState<Entity> = {
ids: EntityId[];
};

export type NamedEntityState<Entity, Collection extends string> = {
[K in keyof EntityState<Entity> as `${Collection}${Capitalize<K>}`]: EntityState<Entity>[K];
};
export type NamedEntityState<Entity, Collection extends string> = Prettify<
{
[K in `${Collection}EntityMap`]: EntityMap<Entity>;
} & {
[K in `${Collection}Ids`]: EntityId[];
}
>;

export type EntityProps<Entity> = {
entities: Signal<Entity[]>;
Expand Down

0 comments on commit 4f7181f

Please sign in to comment.