From 0e377c9dfef2f1041110c982e6570edcfdf9ae17 Mon Sep 17 00:00:00 2001 From: Tom Crockett Date: Sat, 21 Apr 2018 18:06:13 -0700 Subject: [PATCH 1/2] Make creation function argument optional for variants of type {} --- src/index.spec.ts | 4 ++++ src/index.ts | 8 +++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/index.spec.ts b/src/index.spec.ts index 50dca6d..c2285a9 100644 --- a/src/index.spec.ts +++ b/src/index.spec.ts @@ -4,6 +4,7 @@ describe('merged', () => { const Foo = unionize({ x: ofType<{ n: number }>(), y: ofType<{ s: string }>(), + z: ofType<{}>(), }); let foo: typeof Foo._Union; @@ -17,6 +18,7 @@ describe('merged', () => { tag: 'x', n: 3, }); + expect(Foo.z()).toEqual(Foo.z({})); }); it('predicates', () => { @@ -34,6 +36,7 @@ describe('merged', () => { Foo.match({ x: ({ n }) => n + 9, y: ({ s }) => s.length, + z: () => 42, })(foo), ).toBe(12); expect( @@ -49,6 +52,7 @@ describe('merged', () => { Foo.match(foo, { x: ({ n }) => n + 9, y: ({ s }) => s.length, + z: () => 42, }), ).toBe(12); expect( diff --git a/src/index.ts b/src/index.ts index 973b05c..9ba12e0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,9 @@ export type Unionized = { } & Creators; export type Creators = { - [T in keyof Record]: (value: Record[T]) => TaggedRecord[keyof TaggedRecord] + [T in keyof Record]: {} extends Record[T] + ? ((value?: {}) => TaggedRecord[keyof TaggedRecord]) + : ((value: Record[T]) => TaggedRecord[keyof TaggedRecord]) }; export type Predicates = { @@ -88,8 +90,8 @@ export function unionize(record: Record, config?: { value?: string; tag? const creators = {} as Creators; for (const tag in record) { - creators[tag] = (value: any) => - valProp ? { [tagProp]: tag, [valProp]: value } : { ...value, [tagProp]: tag }; + creators[tag] = ((value = {}) => + valProp ? { [tagProp]: tag, [valProp]: value } : { ...value, [tagProp]: tag }) as any; } const is = {} as Predicates; From b8f9c2cce8812cacc5250fbb98240c0b7fcabfe2 Mon Sep 17 00:00:00 2001 From: Tom Crockett Date: Sat, 21 Apr 2018 18:38:54 -0700 Subject: [PATCH 2/2] Update README --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c6572d5..04c71cd 100644 --- a/README.md +++ b/README.md @@ -16,9 +16,10 @@ import { unionize, ofType } from 'unionize' // Define a record mapping tag literals to value types const Action = unionize({ - ADD_TODO: ofType<{ id: string; text: string }>(), - SET_VISIBILITY_FILTER: ofType<'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED'>(), - TOGGLE_TODO: ofType<{ id: string }>() + ADD_TODO: ofType<{ id: string; text: string }>(), + SET_VISIBILITY_FILTER: ofType<'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED'>(), + TOGGLE_TODO: ofType<{ id: string }>(), + CLEAR_TODOS: {}, // For "empty" types, just use {} }, // optionally override tag and/or value property names { @@ -39,6 +40,7 @@ type Action = | { type: ADD_TODO; payload: { id: string; text: string } } | { type: SET_VISIBILITY_FILTER; payload: 'SHOW_ALL' | 'SHOW_ACTIVE' | 'SHOW_COMPLETED' } | { type: TOGGLE_TODO; payload: { id: string } } + | { type: CLEAR_TODOS; payload: {} } ``` Having done that, you now have at your disposal: @@ -48,6 +50,7 @@ Having done that, you now have at your disposal: ```ts store.dispatch(Action.ADD_TODO({ id: 'c819bbc1', text: 'Take out the trash' })); store.dispatch(Action.SET_VISIBILITY_FILTER('SHOW_COMPLETED')); +store.dispatch(Action.CLEAR_TODOS()); // no argument required if value type is {} ``` #### Match expressions