Skip to content

Commit 0a13c4d

Browse files
timdeschryvermarkostanimirovic
authored andcommitted
feat(store): add selectSignal options
1 parent 503e9d8 commit 0a13c4d

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

modules/store/spec/types/select_signal.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ describe('Store.selectSignal()', () => {
4141
`const selector = store.selectSignal(s => s.foo.bar);`
4242
).toInfer('selector', 'Signal<{ baz: []; }>');
4343
});
44+
45+
it('should infer correctly (with options)', () => {
46+
expectSnippet(
47+
`const selector = store.selectSignal(s => s.foo, {equal: (a, b) => a === b});`
48+
).toInfer('selector', 'Signal<{ bar: { baz: []; }; }>');
49+
});
4450
});
4551

4652
describe('with selectors', () => {
@@ -53,6 +59,16 @@ describe('Store.selectSignal()', () => {
5359
`const selector = store.selectSignal(barSelector);`
5460
).toInfer('selector', 'Signal<{ baz: []; }>');
5561
});
62+
63+
it('should infer correctly (with options)', () => {
64+
expectSnippet(
65+
`const selector = store.selectSignal(fooSelector, {equal: (a,b) => a === b});`
66+
).toInfer('selector', 'Signal<{ bar: { baz: []; }; }>');
67+
68+
expectSnippet(
69+
`const selector = store.selectSignal(barSelector);`
70+
).toInfer('selector', 'Signal<{ baz: []; }>');
71+
});
5672
});
5773
});
5874
});

modules/store/src/models.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { type ValueEqualityFn } from '@angular/core';
2+
13
export interface Action {
24
type: string;
35
}
@@ -169,3 +171,10 @@ export interface RuntimeChecks {
169171
*/
170172
strictActionTypeUniqueness?: boolean;
171173
}
174+
175+
export interface SelectSignalOptions<T> {
176+
/**
177+
* A comparison function which defines equality for select results.
178+
*/
179+
equal?: ValueEqualityFn<T>;
180+
}

modules/store/src/store.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@ import { Observable, Observer, Operator } from 'rxjs';
44
import { distinctUntilChanged, map, pluck } from 'rxjs/operators';
55

66
import { ActionsSubject } from './actions_subject';
7-
import { Action, ActionReducer, FunctionIsNotAllowed } from './models';
7+
import {
8+
Action,
9+
ActionReducer,
10+
SelectSignalOptions,
11+
FunctionIsNotAllowed,
12+
} from './models';
813
import { ReducerManager } from './reducer_manager';
914
import { StateObservable } from './state';
1015
import { toSignal } from './to_signal';
@@ -101,9 +106,13 @@ export class Store<T = object>
101106
* Returns a signal of the provided selector.
102107
*
103108
* @param selector selector function
109+
* @param options select signal options
104110
*/
105-
selectSignal<K>(selector: (state: T) => K): Signal<K> {
106-
return computed(() => selector(this.state()));
111+
selectSignal<K>(
112+
selector: (state: T) => K,
113+
options?: SelectSignalOptions<K>
114+
): Signal<K> {
115+
return computed(() => selector(this.state()), { equal: options?.equal });
107116
}
108117

109118
override lift<R>(operator: Operator<T, R>): Store<R> {

0 commit comments

Comments
 (0)