Skip to content

Commit 33241cb

Browse files
alex-okrushkobrandonroberts
authored andcommitted
fix(store): allow union of types in props (#2301)
1 parent 711c30d commit 33241cb

File tree

3 files changed

+37
-22
lines changed

3 files changed

+37
-22
lines changed

modules/store/spec/action_creator.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,28 @@ describe('Action Creators', () => {
7676
narrow(foo({ foo: 42 }));
7777
});
7878

79+
it('should allow the union of types in props', () => {
80+
interface A {
81+
sameProp: 'A';
82+
}
83+
interface B {
84+
sameProp: 'B';
85+
extraProp: string;
86+
}
87+
type U = A | B;
88+
const foo = createAction('FOO', props<U>());
89+
90+
const fooA = foo({ sameProp: 'A' });
91+
const fooB = foo({ sameProp: 'B', extraProp: 'allowed' });
92+
93+
expect(fooA).toEqual({ type: 'FOO', sameProp: 'A' });
94+
expect(fooB).toEqual({
95+
type: 'FOO',
96+
sameProp: 'B',
97+
extraProp: 'allowed',
98+
});
99+
});
100+
79101
it('should be serializable', () => {
80102
const foo = createAction('FOO', props<{ foo: number }>());
81103
const fooAction = foo({ foo: 42 });

modules/store/src/action_creator.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import {
33
ActionCreator,
44
TypedAction,
55
FunctionWithParametersType,
6-
PropsReturnType,
7-
DisallowArraysAndTypeProperty,
6+
NotAllowedCheck,
7+
Props,
88
} from './models';
99

1010
// Action creators taken from ts-action library and modified a bit to better
@@ -15,15 +15,15 @@ export function createAction<T extends string>(
1515
): ActionCreator<T, () => TypedAction<T>>;
1616
export function createAction<T extends string, P extends object>(
1717
type: T,
18-
config: { _as: 'props'; _p: P }
19-
): ActionCreator<T, (props: P) => P & TypedAction<T>>;
18+
config: Props<P>
19+
): ActionCreator<T, (props: P & NotAllowedCheck<P>) => P & TypedAction<T>>;
2020
export function createAction<
2121
T extends string,
2222
P extends any[],
2323
R extends object
2424
>(
2525
type: T,
26-
creator: Creator<P, DisallowArraysAndTypeProperty<R>>
26+
creator: Creator<P, R> & NotAllowedCheck<R>
2727
): FunctionWithParametersType<P, R & TypedAction<T>> & TypedAction<T>;
2828
/**
2929
* @description
@@ -121,10 +121,8 @@ export function createAction<T extends string, C extends Creator>(
121121
}
122122
}
123123

124-
export function props<P extends object>(): PropsReturnType<P> {
125-
// the return type does not match TypePropertyIsNotAllowed, so double casting
126-
// is used.
127-
return ({ _as: 'props', _p: undefined! } as unknown) as PropsReturnType<P>;
124+
export function props<P extends object>(): Props<P> {
125+
return { _as: 'props', _p: undefined! };
128126
}
129127

130128
export function union<

modules/store/src/models.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,6 @@ export const arraysAreNotAllowedMsg =
5757
'arrays are not allowed in action creators';
5858
type ArraysAreNotAllowed = typeof arraysAreNotAllowedMsg;
5959

60-
export type DisallowArraysAndTypeProperty<T> = T extends any[]
61-
? ArraysAreNotAllowed
62-
: T extends { type: any } ? TypePropertyIsNotAllowed : T;
63-
6460
export const typePropertyIsNotAllowedMsg =
6561
'type property is not allowed in action creators';
6662
type TypePropertyIsNotAllowed = typeof typePropertyIsNotAllowedMsg;
@@ -75,17 +71,11 @@ export type FunctionIsNotAllowed<
7571
export type Creator<
7672
P extends any[] = any[],
7773
R extends object = object
78-
> = R extends any[]
79-
? ArraysAreNotAllowed
80-
: R extends { type: any }
81-
? TypePropertyIsNotAllowed
82-
: FunctionWithParametersType<P, R>;
74+
> = FunctionWithParametersType<P, R>;
8375

84-
export type PropsReturnType<T extends object> = T extends any[]
76+
export type NotAllowedCheck<T extends object> = T extends any[]
8577
? ArraysAreNotAllowed
86-
: T extends { type: any }
87-
? TypePropertyIsNotAllowed
88-
: { _as: 'props'; _p: T };
78+
: T extends { type: any } ? TypePropertyIsNotAllowed : unknown;
8979

9080
/**
9181
* See `Creator`.
@@ -95,6 +85,11 @@ export type ActionCreator<
9585
C extends Creator = Creator
9686
> = C & TypedAction<T>;
9787

88+
export interface Props<T> {
89+
_as: 'props';
90+
_p: T;
91+
}
92+
9893
export type FunctionWithParametersType<P extends unknown[], R = void> = (
9994
...args: P
10095
) => R;

0 commit comments

Comments
 (0)