Skip to content

Commit

Permalink
fix(signal-slice): typing for Subject with union type (#169)
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuamorony authored Nov 21, 2023
1 parent e4ffaee commit 746c0fc
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 9 deletions.
22 changes: 22 additions & 0 deletions libs/ngxtension/signal-slice/src/signal-slice.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe(signalSlice.name, () => {
lastName: 'morony',
},
age: 30,
powerLevel: 50 as number | null,
likes: ['angular', 'typescript'],
};

Expand Down Expand Up @@ -167,6 +168,27 @@ describe(signalSlice.name, () => {
});
});

it('should accept an external subject with arguments as an action', () => {
TestBed.runInInjectionContext(() => {
const testAge = 50;

const triggerWithAmount$ = new Subject<number>();
const state = signalSlice({
initialState,
sources: [
triggerWithAmount$.pipe(map((amount) => ({ age: amount }))),
],
actionSources: {
triggerWithAmount: triggerWithAmount$,
},
});

state.triggerWithAmount(testAge);

expect(state().age).toEqual(testAge);
});
});

it('should create action that updates signal asynchronously', () => {
TestBed.runInInjectionContext(() => {
const testAge = 35;
Expand Down
23 changes: 14 additions & 9 deletions libs/ngxtension/signal-slice/src/signal-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,26 @@ type Effects<TEffects extends NamedEffects> = {
[K in keyof TEffects]: EffectRef;
};

type Action<TSignalValue, TValue> = TValue extends void
type Action<TSignalValue, TValue> = TValue extends [void]
? () => Promise<TSignalValue>
: unknown extends TValue
: [unknown] extends TValue
? () => Promise<TSignalValue>
: (value: TValue | Observable<TValue>) => Promise<TSignalValue>;
: (
value: TValue extends [infer TInferred]
? TInferred | Observable<TInferred>
: TValue | Observable<TValue>
) => Promise<TSignalValue>;

type ActionMethod<
TSignalValue,
TActionSource extends NamedActionSources<TSignalValue>[string]
> = TActionSource extends
| ((state: Signal<TSignalValue>, value: infer TValue) => any)
| Subject<infer TValue>
? TValue extends Observable<infer TObservableValue>
? Action<TSignalValue, TObservableValue>
: Action<TSignalValue, TValue>
> = TActionSource extends (
state: Signal<TSignalValue>,
value: Observable<infer TObservableValue>
) => any
? Action<TSignalValue, [TObservableValue]>
: TActionSource extends Subject<infer TSubjectValue>
? Action<TSignalValue, [TSubjectValue]>
: never;

type ActionMethods<
Expand Down

0 comments on commit 746c0fc

Please sign in to comment.