Skip to content

Commit

Permalink
feat: add getType helper
Browse files Browse the repository at this point in the history
export getType to public API
  • Loading branch information
Mohammad Hasani committed Jan 17, 2019
1 parent c521828 commit f8e4dc5
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/__tests__/__snapshots__/get-type.dts.spec.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`getType getType(viaToString) (type) should match snapshot: getType getType(viaToString) 1`] = `"\\"[Todo] truncate\\""`;

exports[`getType getType(viaType) (type) should match snapshot: getType getType(viaType) 1`] = `"\\"[Todo] truncate\\""`;
19 changes: 19 additions & 0 deletions src/__tests__/get-type.dts.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { getType } from '../get-type'

// @dts-jest:group getType

const type = '[Todo] truncate'
type Type = typeof type

const viaType = { type: <Type>type }
const viaToString = {
toString(): Type {
return type
},
}

// @dts-jest:pass:snap
getType(viaType)

// @dts-jest:pass:snap
getType(viaToString)
28 changes: 28 additions & 0 deletions src/__tests__/get-type.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { getType } from '../get-type'

describe('getType', () => {
it('should throw error when action creator does not provide either .type nor toString()', () => {
const type = '[Todo] truncate'
const actionCreator = () => ({ type })

expect(() => getType(actionCreator)).toThrow()
})

it('should get action type of action creator via .type', () => {
const type = '[Todo] truncate'
const actionCreator = Object.assign(() => ({ type }), { type })

expect(getType(actionCreator)).toBe(type)
})

it('should get action type of action creator via toString()', () => {
const type = '[Todo] truncate'
const actionCreator = Object.assign(() => ({ type }), {
toString() {
return type
},
})

expect(getType(actionCreator)).toBe(type)
})
})
29 changes: 29 additions & 0 deletions src/get-type.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Map action creator to it's contained action type
* @description it gets an object with at least a type property or overridden toString method and returns it.
* @example
* const increment = createAction('[Counter] increment')
* getType(increment) //=> '[Counter] increment'
* @example
* getType({ type: 'TEST' }) //=> 'TEST'
* @example
* getType({
* toString() { return 'TEST' }
* }) //=> 'TEST'
*/
export function getType<
AC extends { type?: string; toString(): string } | { type: string },
Type extends string = AC extends { type: infer T }
? T
: AC extends { toString(): infer U }
? U
: never
>(actionCreator: AC) {
if (!actionCreator.type && !actionCreator.hasOwnProperty('toString')) {
throw new Error(
`Action creator that has been passed to getType() does not provide any API to expose action type. You can use createAction() to create an action creator without any unsense errors.`
)
}

return <Type>(actionCreator.type || actionCreator.toString())
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './action'
export { createAction, ActionCreator } from './create-action'
export { getType } from './get-type'

0 comments on commit f8e4dc5

Please sign in to comment.