From ab5254a358aaa84020599ea0da26a030efe6d298 Mon Sep 17 00:00:00 2001 From: aokrushko Date: Thu, 2 Jan 2020 19:58:15 -0500 Subject: [PATCH 1/2] fix(store): allow union of types in props --- modules/store/spec/action_creator.spec.ts | 22 ++++++++++++++++++++++ modules/store/src/action_creator.ts | 13 +++++-------- modules/store/src/models.ts | 12 +++--------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/modules/store/spec/action_creator.spec.ts b/modules/store/spec/action_creator.spec.ts index ddad376ecc..02e0d1c5d6 100644 --- a/modules/store/spec/action_creator.spec.ts +++ b/modules/store/spec/action_creator.spec.ts @@ -76,6 +76,28 @@ describe('Action Creators', () => { narrow(foo({ foo: 42 })); }); + it('should allow the union of types in props', () => { + interface A { + sameProp: 'A'; + } + interface B { + sameProp: 'B'; + extraProp: string; + } + type U = A | B; + const foo = createAction('FOO', props()); + + const fooA = foo({ sameProp: 'A' }); + const fooB = foo({ sameProp: 'B', extraProp: 'allowed' }); + + expect(fooA).toEqual({ type: 'FOO', sameProp: 'A' }); + expect(fooB).toEqual({ + type: 'FOO', + sameProp: 'B', + extraProp: 'allowed', + }); + }); + it('should be serializable', () => { const foo = createAction('FOO', props<{ foo: number }>()); const fooAction = foo({ foo: 42 }); diff --git a/modules/store/src/action_creator.ts b/modules/store/src/action_creator.ts index 585ff6daa6..ac04889361 100644 --- a/modules/store/src/action_creator.ts +++ b/modules/store/src/action_creator.ts @@ -3,8 +3,7 @@ import { ActionCreator, TypedAction, FunctionWithParametersType, - PropsReturnType, - DisallowArraysAndTypeProperty, + NotAllowedCheck, } from './models'; // Action creators taken from ts-action library and modified a bit to better @@ -16,14 +15,14 @@ export function createAction( export function createAction( type: T, config: { _as: 'props'; _p: P } -): ActionCreator P & TypedAction>; +): ActionCreator) => P & TypedAction>; export function createAction< T extends string, P extends any[], R extends object >( type: T, - creator: Creator> + creator: Creator & NotAllowedCheck ): FunctionWithParametersType> & TypedAction; /** * @description @@ -121,10 +120,8 @@ export function createAction( } } -export function props

(): PropsReturnType

{ - // the return type does not match TypePropertyIsNotAllowed, so double casting - // is used. - return ({ _as: 'props', _p: undefined! } as unknown) as PropsReturnType

; +export function props

(): { _as: 'props'; _p: P } { + return { _as: 'props', _p: undefined! }; } export function union< diff --git a/modules/store/src/models.ts b/modules/store/src/models.ts index 542f063b86..ce1a2f2b4c 100644 --- a/modules/store/src/models.ts +++ b/modules/store/src/models.ts @@ -75,17 +75,11 @@ export type FunctionIsNotAllowed< export type Creator< P extends any[] = any[], R extends object = object -> = R extends any[] - ? ArraysAreNotAllowed - : R extends { type: any } - ? TypePropertyIsNotAllowed - : FunctionWithParametersType; +> = FunctionWithParametersType; -export type PropsReturnType = T extends any[] +export type NotAllowedCheck = T extends any[] ? ArraysAreNotAllowed - : T extends { type: any } - ? TypePropertyIsNotAllowed - : { _as: 'props'; _p: T }; + : T extends { type: any } ? TypePropertyIsNotAllowed : unknown; /** * See `Creator`. From 7ed56c88f1952fba53c853d6baa20fbe874f0c37 Mon Sep 17 00:00:00 2001 From: aokrushko Date: Mon, 6 Jan 2020 20:05:19 -0500 Subject: [PATCH 2/2] Remove DisallowArraysAndTypeProperty and create Props --- modules/store/src/action_creator.ts | 5 +++-- modules/store/src/models.ts | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/store/src/action_creator.ts b/modules/store/src/action_creator.ts index ac04889361..492fbedf8d 100644 --- a/modules/store/src/action_creator.ts +++ b/modules/store/src/action_creator.ts @@ -4,6 +4,7 @@ import { TypedAction, FunctionWithParametersType, NotAllowedCheck, + Props, } from './models'; // Action creators taken from ts-action library and modified a bit to better @@ -14,7 +15,7 @@ export function createAction( ): ActionCreator TypedAction>; export function createAction( type: T, - config: { _as: 'props'; _p: P } + config: Props

): ActionCreator) => P & TypedAction>; export function createAction< T extends string, @@ -120,7 +121,7 @@ export function createAction( } } -export function props

(): { _as: 'props'; _p: P } { +export function props

(): Props

{ return { _as: 'props', _p: undefined! }; } diff --git a/modules/store/src/models.ts b/modules/store/src/models.ts index ce1a2f2b4c..e6b56a872f 100644 --- a/modules/store/src/models.ts +++ b/modules/store/src/models.ts @@ -57,10 +57,6 @@ export const arraysAreNotAllowedMsg = 'arrays are not allowed in action creators'; type ArraysAreNotAllowed = typeof arraysAreNotAllowedMsg; -export type DisallowArraysAndTypeProperty = T extends any[] - ? ArraysAreNotAllowed - : T extends { type: any } ? TypePropertyIsNotAllowed : T; - export const typePropertyIsNotAllowedMsg = 'type property is not allowed in action creators'; type TypePropertyIsNotAllowed = typeof typePropertyIsNotAllowedMsg; @@ -89,6 +85,11 @@ export type ActionCreator< C extends Creator = Creator > = C & TypedAction; +export interface Props { + _as: 'props'; + _p: T; +} + export type FunctionWithParametersType

= ( ...args: P ) => R;