ts-redux-actions
Advanced tools
Comparing version 1.0.0-beta5 to 1.0.0-rc.0
@@ -1,13 +0,5 @@ | ||
export declare type ActionCreatorFunction<TS extends string> = ((...args: any[]) => { | ||
type: TS; | ||
payload?: any; | ||
meta?: any; | ||
error?: boolean; | ||
}); | ||
export declare type TSActionCreator<AC, T extends string> = AC & { | ||
readonly type: T; | ||
}; | ||
export declare function createAction<TS extends string, AC extends (() => { | ||
type: TS; | ||
})>(typeString: TS): TSActionCreator<AC, TS>; | ||
export declare function createAction<TS extends string, AC extends ActionCreatorFunction<TS>>(typeString: TS, creatorFunction: AC): TSActionCreator<AC, TS>; | ||
import { FluxStandardAction, TypeGetter } from '.'; | ||
export declare function createAction<T extends string, AC extends (...args: any[]) => FluxStandardAction<T>>(typeString: T, creatorFunction: AC): AC & TypeGetter<T>; | ||
export declare function createAction<T extends string, AC extends () => { | ||
type: T; | ||
}>(typeString: T): AC & TypeGetter<T>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function createAction(typeString, creatorFunction) { | ||
if (creatorFunction) { | ||
var actionCreator; | ||
if (creatorFunction != null) { | ||
if (typeof creatorFunction !== 'function') { | ||
throw new Error('second argument is not a function'); | ||
} | ||
var actionCreator = creatorFunction; | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = creatorFunction; | ||
} | ||
else { | ||
var actionCreator = function () { return ({ type: typeString }); }; | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = function () { return ({ type: typeString }); }; | ||
} | ||
if (typeString != null) { | ||
if (typeof typeString !== 'string') { | ||
throw new Error('first argument is not a type string'); | ||
} | ||
actionCreator.getType = function () { return typeString; }; | ||
} | ||
else { | ||
throw new Error('first argument is missing'); | ||
} | ||
return actionCreator; | ||
} | ||
exports.createAction = createAction; | ||
//# sourceMappingURL=create-action.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var _1 = require("."); | ||
describe('Redux Utils', function () { | ||
describe('createAction', function () { | ||
it('no payload', function () { | ||
var increment = _1.createAction('INCREMENT'); | ||
expect(increment()).toEqual({ type: 'INCREMENT' }); | ||
expect(increment.type).toBe('INCREMENT'); | ||
describe('createAction', function () { | ||
it('no payload', function () { | ||
var increment = _1.createAction('INCREMENT'); | ||
var action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
var type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('no payload alternative', function () { | ||
var increment = _1.createAction('INCREMENT', function () { return ({ type: 'INCREMENT' }); }); | ||
var action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
var type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('with payload', function () { | ||
var add = _1.createAction('ADD', function (amount) { return ({ type: 'ADD', payload: amount }); }); | ||
var action = add(10); | ||
expect(action).toEqual({ type: 'ADD', payload: 10 }); | ||
var type = add.getType(); | ||
expect(type).toBe('ADD'); | ||
}); | ||
it('with payload and meta', function () { | ||
var notify = _1.createAction('NOTIFY', function (username, message) { return ({ | ||
type: 'NOTIFY', | ||
payload: { message: username + ": " + message }, | ||
meta: { username: username, message: message }, | ||
}); }); | ||
var action = notify('Piotr', 'Hello!'); | ||
expect(action).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
it('with payload', function () { | ||
var add = _1.createAction('ADD', function (amount) { return ({ type: 'ADD', payload: amount }); }); | ||
expect(add(10)).toEqual({ type: 'ADD', payload: 10 }); | ||
expect(add.type).toBe('ADD'); | ||
var type = notify.getType(); | ||
expect(type).toBe('NOTIFY'); | ||
}); | ||
it('with payload and no params', function () { | ||
var showNotification = _1.createAction('SHOW_NOTIFICATION', function () { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); }); | ||
var action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
it('with payload and meta', function () { | ||
var notify = _1.createAction('NOTIFY', function (username, message) { return ({ | ||
type: 'NOTIFY', | ||
payload: { message: username + ": " + message }, | ||
meta: { username: username, message: message }, | ||
}); }); | ||
expect(notify('Piotr', 'Hello!')).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
expect(notify.type).toBe('NOTIFY'); | ||
var type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with payload and optional param', function () { | ||
var showNotification = _1.createAction('SHOW_NOTIFICATION', function (message) { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
}); }); | ||
var action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
it('with payload and no params', function () { | ||
var showNotification = _1.createAction('SHOW_NOTIFICATION', function () { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); }); | ||
var result = showNotification(); | ||
expect(result).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
var type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with meta and no params', function () { | ||
var showError = _1.createAction('SHOW_ERROR', function () { return ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); }); | ||
var action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
it('with payload and optional param', function () { | ||
var showNotification = _1.createAction('SHOW_NOTIFICATION', function (message) { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
}); }); | ||
expect(showNotification()).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
var type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', function () { | ||
var showError = _1.createAction('SHOW_ERROR', function (message) { return ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
}); }); | ||
var action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
it('with meta and no params', function () { | ||
var showError = _1.createAction('SHOW_ERROR', function () { return ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); }); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', function () { | ||
var showError = _1.createAction('SHOW_ERROR', function (message) { return ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
}); }); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
var type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
}); | ||
//# sourceMappingURL=create-action.spec.js.map |
export * from './type-utils'; | ||
export * from './redux-types'; | ||
export * from './get-type'; | ||
export * from './create-action'; |
@@ -5,3 +5,4 @@ "use strict"; | ||
tslib_1.__exportStar(require("./type-utils"), exports); | ||
tslib_1.__exportStar(require("./get-type"), exports); | ||
tslib_1.__exportStar(require("./create-action"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -13,7 +13,7 @@ export declare type EmptyAction<T extends string> = { | ||
}; | ||
export declare type FluxStandardAction<T extends string, P, M = undefined> = { | ||
export declare type FluxStandardAction<T extends string, P = any, M = any> = { | ||
type: T; | ||
payload: P | Error; | ||
payload?: P; | ||
meta?: M; | ||
error?: boolean; | ||
}; |
@@ -1,13 +0,5 @@ | ||
export declare type ActionCreatorFunction<TS extends string> = ((...args: any[]) => { | ||
type: TS; | ||
payload?: any; | ||
meta?: any; | ||
error?: boolean; | ||
}); | ||
export declare type TSActionCreator<AC, T extends string> = AC & { | ||
readonly type: T; | ||
}; | ||
export declare function createAction<TS extends string, AC extends (() => { | ||
type: TS; | ||
})>(typeString: TS): TSActionCreator<AC, TS>; | ||
export declare function createAction<TS extends string, AC extends ActionCreatorFunction<TS>>(typeString: TS, creatorFunction: AC): TSActionCreator<AC, TS>; | ||
import { FluxStandardAction, TypeGetter } from '.'; | ||
export declare function createAction<T extends string, AC extends (...args: any[]) => FluxStandardAction<T>>(typeString: T, creatorFunction: AC): AC & TypeGetter<T>; | ||
export declare function createAction<T extends string, AC extends () => { | ||
type: T; | ||
}>(typeString: T): AC & TypeGetter<T>; |
export function createAction(typeString, creatorFunction) { | ||
if (creatorFunction) { | ||
var actionCreator; | ||
if (creatorFunction != null) { | ||
if (typeof creatorFunction !== 'function') { | ||
throw new Error('second argument is not a function'); | ||
} | ||
var actionCreator = creatorFunction; | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = creatorFunction; | ||
} | ||
else { | ||
var actionCreator = function () { return ({ type: typeString }); }; | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = function () { return ({ type: typeString }); }; | ||
} | ||
if (typeString != null) { | ||
if (typeof typeString !== 'string') { | ||
throw new Error('first argument is not a type string'); | ||
} | ||
actionCreator.getType = function () { return typeString; }; | ||
} | ||
else { | ||
throw new Error('first argument is missing'); | ||
} | ||
return actionCreator; | ||
} | ||
//# sourceMappingURL=create-action.js.map |
import { createAction } from '.'; | ||
describe('Redux Utils', function () { | ||
describe('createAction', function () { | ||
it('no payload', function () { | ||
var increment = createAction('INCREMENT'); | ||
expect(increment()).toEqual({ type: 'INCREMENT' }); | ||
expect(increment.type).toBe('INCREMENT'); | ||
describe('createAction', function () { | ||
it('no payload', function () { | ||
var increment = createAction('INCREMENT'); | ||
var action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
var type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('no payload alternative', function () { | ||
var increment = createAction('INCREMENT', function () { return ({ type: 'INCREMENT' }); }); | ||
var action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
var type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('with payload', function () { | ||
var add = createAction('ADD', function (amount) { return ({ type: 'ADD', payload: amount }); }); | ||
var action = add(10); | ||
expect(action).toEqual({ type: 'ADD', payload: 10 }); | ||
var type = add.getType(); | ||
expect(type).toBe('ADD'); | ||
}); | ||
it('with payload and meta', function () { | ||
var notify = createAction('NOTIFY', function (username, message) { return ({ | ||
type: 'NOTIFY', | ||
payload: { message: username + ": " + message }, | ||
meta: { username: username, message: message }, | ||
}); }); | ||
var action = notify('Piotr', 'Hello!'); | ||
expect(action).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
it('with payload', function () { | ||
var add = createAction('ADD', function (amount) { return ({ type: 'ADD', payload: amount }); }); | ||
expect(add(10)).toEqual({ type: 'ADD', payload: 10 }); | ||
expect(add.type).toBe('ADD'); | ||
var type = notify.getType(); | ||
expect(type).toBe('NOTIFY'); | ||
}); | ||
it('with payload and no params', function () { | ||
var showNotification = createAction('SHOW_NOTIFICATION', function () { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); }); | ||
var action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
it('with payload and meta', function () { | ||
var notify = createAction('NOTIFY', function (username, message) { return ({ | ||
type: 'NOTIFY', | ||
payload: { message: username + ": " + message }, | ||
meta: { username: username, message: message }, | ||
}); }); | ||
expect(notify('Piotr', 'Hello!')).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
expect(notify.type).toBe('NOTIFY'); | ||
var type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with payload and optional param', function () { | ||
var showNotification = createAction('SHOW_NOTIFICATION', function (message) { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
}); }); | ||
var action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
it('with payload and no params', function () { | ||
var showNotification = createAction('SHOW_NOTIFICATION', function () { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); }); | ||
var result = showNotification(); | ||
expect(result).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
var type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with meta and no params', function () { | ||
var showError = createAction('SHOW_ERROR', function () { return ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); }); | ||
var action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
it('with payload and optional param', function () { | ||
var showNotification = createAction('SHOW_NOTIFICATION', function (message) { return ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
}); }); | ||
expect(showNotification()).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
var type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', function () { | ||
var showError = createAction('SHOW_ERROR', function (message) { return ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
}); }); | ||
var action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
it('with meta and no params', function () { | ||
var showError = createAction('SHOW_ERROR', function () { return ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); }); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', function () { | ||
var showError = createAction('SHOW_ERROR', function (message) { return ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
}); }); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
var type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
}); | ||
//# sourceMappingURL=create-action.spec.js.map |
export * from './type-utils'; | ||
export * from './redux-types'; | ||
export * from './get-type'; | ||
export * from './create-action'; |
export * from './type-utils'; | ||
export * from './get-type'; | ||
export * from './create-action'; | ||
//# sourceMappingURL=index.js.map |
@@ -13,7 +13,7 @@ export declare type EmptyAction<T extends string> = { | ||
}; | ||
export declare type FluxStandardAction<T extends string, P, M = undefined> = { | ||
export declare type FluxStandardAction<T extends string, P = any, M = any> = { | ||
type: T; | ||
payload: P | Error; | ||
payload?: P; | ||
meta?: M; | ||
error?: boolean; | ||
}; |
@@ -1,13 +0,5 @@ | ||
export declare type ActionCreatorFunction<TS extends string> = ((...args: any[]) => { | ||
type: TS; | ||
payload?: any; | ||
meta?: any; | ||
error?: boolean; | ||
}); | ||
export declare type TSActionCreator<AC, T extends string> = AC & { | ||
readonly type: T; | ||
}; | ||
export declare function createAction<TS extends string, AC extends (() => { | ||
type: TS; | ||
})>(typeString: TS): TSActionCreator<AC, TS>; | ||
export declare function createAction<TS extends string, AC extends ActionCreatorFunction<TS>>(typeString: TS, creatorFunction: AC): TSActionCreator<AC, TS>; | ||
import { FluxStandardAction, TypeGetter } from '.'; | ||
export declare function createAction<T extends string, AC extends (...args: any[]) => FluxStandardAction<T>>(typeString: T, creatorFunction: AC): AC & TypeGetter<T>; | ||
export declare function createAction<T extends string, AC extends () => { | ||
type: T; | ||
}>(typeString: T): AC & TypeGetter<T>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function createAction(typeString, creatorFunction) { | ||
if (creatorFunction) { | ||
let actionCreator; | ||
if (creatorFunction != null) { | ||
if (typeof creatorFunction !== 'function') { | ||
throw new Error('second argument is not a function'); | ||
} | ||
const actionCreator = creatorFunction; | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = creatorFunction; | ||
} | ||
else { | ||
const actionCreator = () => ({ type: typeString }); | ||
actionCreator.type = typeString; | ||
return actionCreator; | ||
actionCreator = () => ({ type: typeString }); | ||
} | ||
if (typeString != null) { | ||
if (typeof typeString !== 'string') { | ||
throw new Error('first argument is not a type string'); | ||
} | ||
actionCreator.getType = () => typeString; | ||
} | ||
else { | ||
throw new Error('first argument is missing'); | ||
} | ||
return actionCreator; | ||
} | ||
exports.createAction = createAction; | ||
//# sourceMappingURL=create-action.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const _1 = require("."); | ||
describe('Redux Utils', () => { | ||
describe('createAction', () => { | ||
it('no payload', () => { | ||
const increment = _1.createAction('INCREMENT'); | ||
expect(increment()).toEqual({ type: 'INCREMENT' }); | ||
expect(increment.type).toBe('INCREMENT'); | ||
describe('createAction', () => { | ||
it('no payload', () => { | ||
const increment = _1.createAction('INCREMENT'); | ||
const action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
const type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('no payload alternative', () => { | ||
const increment = _1.createAction('INCREMENT', () => ({ type: 'INCREMENT' })); | ||
const action = increment(); | ||
expect(action).toEqual({ type: 'INCREMENT' }); | ||
const type = increment.getType(); | ||
expect(type).toBe('INCREMENT'); | ||
}); | ||
it('with payload', () => { | ||
const add = _1.createAction('ADD', (amount) => ({ type: 'ADD', payload: amount })); | ||
const action = add(10); | ||
expect(action).toEqual({ type: 'ADD', payload: 10 }); | ||
const type = add.getType(); | ||
expect(type).toBe('ADD'); | ||
}); | ||
it('with payload and meta', () => { | ||
const notify = _1.createAction('NOTIFY', (username, message) => ({ | ||
type: 'NOTIFY', | ||
payload: { message: `${username}: ${message}` }, | ||
meta: { username, message }, | ||
})); | ||
const action = notify('Piotr', 'Hello!'); | ||
expect(action).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
it('with payload', () => { | ||
const add = _1.createAction('ADD', (amount) => ({ type: 'ADD', payload: amount })); | ||
expect(add(10)).toEqual({ type: 'ADD', payload: 10 }); | ||
expect(add.type).toBe('ADD'); | ||
const type = notify.getType(); | ||
expect(type).toBe('NOTIFY'); | ||
}); | ||
it('with payload and no params', () => { | ||
const showNotification = _1.createAction('SHOW_NOTIFICATION', () => ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
})); | ||
const action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
it('with payload and meta', () => { | ||
const notify = _1.createAction('NOTIFY', (username, message) => ({ | ||
type: 'NOTIFY', | ||
payload: { message: `${username}: ${message}` }, | ||
meta: { username, message }, | ||
})); | ||
expect(notify('Piotr', 'Hello!')).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
expect(notify.type).toBe('NOTIFY'); | ||
const type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with payload and optional param', () => { | ||
const showNotification = _1.createAction('SHOW_NOTIFICATION', (message) => ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
})); | ||
const action = showNotification(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
it('with payload and no params', () => { | ||
const showNotification = _1.createAction('SHOW_NOTIFICATION', () => ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
})); | ||
const result = showNotification(); | ||
expect(result).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: 'default message', | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
const type = showNotification.getType(); | ||
expect(type).toBe('SHOW_NOTIFICATION'); | ||
}); | ||
it('with meta and no params', () => { | ||
const showError = _1.createAction('SHOW_ERROR', () => ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
})); | ||
const action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
it('with payload and optional param', () => { | ||
const showNotification = _1.createAction('SHOW_NOTIFICATION', (message) => ({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: message, | ||
})); | ||
expect(showNotification()).toEqual({ | ||
type: 'SHOW_NOTIFICATION', | ||
payload: undefined, | ||
}); | ||
expect(showNotification.type).toBe('SHOW_NOTIFICATION'); | ||
const type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', () => { | ||
const showError = _1.createAction('SHOW_ERROR', (message) => ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
})); | ||
const action = showError(); | ||
expect(action).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
it('with meta and no params', () => { | ||
const showError = _1.createAction('SHOW_ERROR', () => ({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
})); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
it('with meta and optional param', () => { | ||
const showError = _1.createAction('SHOW_ERROR', (message) => ({ | ||
type: 'SHOW_ERROR', | ||
payload: message, | ||
meta: { type: 'error' }, | ||
})); | ||
expect(showError()).toEqual({ | ||
type: 'SHOW_ERROR', | ||
payload: undefined, | ||
meta: { type: 'error' }, | ||
}); | ||
expect(showError.type).toBe('SHOW_ERROR'); | ||
}); | ||
const type = showError.getType(); | ||
expect(type).toBe('SHOW_ERROR'); | ||
}); | ||
}); | ||
//# sourceMappingURL=create-action.spec.js.map |
export * from './type-utils'; | ||
export * from './redux-types'; | ||
export * from './get-type'; | ||
export * from './create-action'; |
@@ -5,3 +5,4 @@ "use strict"; | ||
tslib_1.__exportStar(require("./type-utils"), exports); | ||
tslib_1.__exportStar(require("./get-type"), exports); | ||
tslib_1.__exportStar(require("./create-action"), exports); | ||
//# sourceMappingURL=index.js.map |
@@ -13,7 +13,7 @@ export declare type EmptyAction<T extends string> = { | ||
}; | ||
export declare type FluxStandardAction<T extends string, P, M = undefined> = { | ||
export declare type FluxStandardAction<T extends string, P = any, M = any> = { | ||
type: T; | ||
payload: P | Error; | ||
payload?: P; | ||
meta?: M; | ||
error?: boolean; | ||
}; |
{ | ||
"name": "ts-redux-actions", | ||
"version": "1.0.0-beta5", | ||
"description": "Typed Redux Actions for TypeScript Projects", | ||
"version": "1.0.0-rc.0", | ||
"description": "Typesafe Redux Action Creators for TypeScript", | ||
"author": "Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)", | ||
@@ -19,3 +19,3 @@ "repository": "https://github.com/piotrwitek/ts-redux-actions", | ||
"clean": "rm -rf es5-commonjs/ es5-module/ jsnext/", | ||
"prepublishOnly": "yarn run clean && yarn run reinstall && yarn run check && yarn run test && yarn run build", | ||
"prepublishOnly": "npm run clean && npm run reinstall && npm run check && npm run test && npm run build", | ||
"check": "npm run lint & npm run tsc", | ||
@@ -27,3 +27,3 @@ "lint": "tslint --project './tsconfig.json'", | ||
"test:watch": "jest --config jest.config.json ./src --watch", | ||
"build": "yarn run build:commonjs & yarn run build:module & yarn run build:jsnext", | ||
"build": "npm run build:commonjs & npm run build:module & npm run build:jsnext", | ||
"build:commonjs": "rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/", | ||
@@ -30,0 +30,0 @@ "build:module": "rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'", |
122
README.md
# TS Redux Actions | ||
> Typed Redux Action Creators for TypeScript | ||
> Typesafe Redux Action Creators for TypeScript | ||
From now on no type errors will sneak in unnoticed through your action creators! | ||
This lib is a part of [`react-redux-typescript`](https://github.com/piotrwitek/react-redux-typescript) library, which is a collection of valuable utilities commonly used across many TypeScript Projects. | ||
- Thoroughly tested both logic and type correctness | ||
- No third-party dependencies | ||
- Semantic Versioning | ||
- No external dependencies | ||
- Output separate bundles for your specific workflow needs: | ||
@@ -17,4 +18,6 @@ - ES5 + CommonJS - `main` | ||
- [Motivation](#motivation) | ||
- [Usage](#usage) | ||
- [Get Started](#get-started) | ||
- [Features](#features) | ||
- [API](#api) | ||
- [getType](#gettype) | ||
- [createAction](#createaction) | ||
@@ -43,19 +46,25 @@ - [~~createActions~~](#createactions) (WIP) | ||
I wasn't satisfied with the API design in [redux-actions](https://redux-actions.js.org/) because of separate payload & meta map callback functions. | ||
It doesn't allow for correct type inference when using TypeScript and it will force you to do an extra effort for explicit type annotations and probably result in more boilerplate when trying to work around it. | ||
I wasn't satisfied with [redux-actions](https://redux-actions.js.org/) with TypeScript because of separate payload & meta map functions which makes it not idiomatic when using with static typing. | ||
What I mean here is it will break your function definition type inference and intellisense in returned "action creator" function (e.g. named arguments will be renamed to generic names like a1, a2, etc... and function arity with optional parameters will break your function signature entirely). | ||
It will force you to do an extra effort for explicit type annotations and probably result in more boilerplate when trying to work around it. | ||
The other common issue with `redux-actions` types and similar solutions are related to losing your function definition type inference and intellisense (named arguments and arity) in resulting "action creator" function which for me is unacceptable. | ||
--- | ||
As a bonus there is a convenient `type` static property on every action creator for common reducer switch case scenarios (can be used to narrow "Discriminated Union" type): | ||
## Get Started | ||
> Important note: Every function created by `createAction` has a convenient `getType` method for a reducer switch case scenarios like below to reduce common boilerplate (works to narrow "Discriminated Union" types, remember to add trailing `!` to remove optional undefined type): | ||
```ts | ||
import { createAction, getType } from 'ts-redux-actions'; | ||
const increment = createAction('INCREMENT'); | ||
// const increment: (() => { | ||
// type: "INCREMENT"; | ||
// }) & { readonly type: "INCREMENT"; } << HERE | ||
// const increment: (() => { type: "INCREMENT"; }) & { getType?(): "INCREMENT"; } << HERE | ||
switch (action.type) { | ||
case increment.type: | ||
// getter on every action creator function: | ||
case increment.getType!(): | ||
return state + 1; | ||
... | ||
... | ||
// alternative helper function for more "FP" style: | ||
case getType(increment): | ||
return state + 1; | ||
default: return state; | ||
@@ -65,6 +74,2 @@ } | ||
--- | ||
## Usage | ||
To highlight the difference in API design and the benefits of "action creator" type inference found in this solution let me show you some usage examples: | ||
@@ -86,5 +91,5 @@ | ||
// only what is expected, no nullables, with inferred literal type in type property! | ||
// const notify1: (() => { | ||
// const notify1: () => { | ||
// type: "NOTIFY"; | ||
// }) & { readonly type: "NOTIFY"; } | ||
// } | ||
``` | ||
@@ -115,6 +120,6 @@ | ||
// still all good! | ||
// const notify2: ((username: string, message?: string | undefined) => { | ||
// const notify2: (username: string, message?: string | undefined) => { | ||
// type: "NOTIFY"; | ||
// payload: { message: string; }; | ||
// }) & { readonly type: "NOTIFY"; } | ||
// } | ||
@@ -148,7 +153,7 @@ ``` | ||
// inference working as expected and compiler will catch all those nasty bugs: | ||
// const: notify: ((username: string, message?: string | undefined) => { | ||
// const: notify: (username: string, message?: string | undefined) => { | ||
// type: "NOTIFY"; | ||
// payload: { message: string; }; | ||
// meta: { username: string; message: string | undefined; }; | ||
// }) & { readonly type: "NOTIFY"; } | ||
// } | ||
``` | ||
@@ -159,15 +164,41 @@ | ||
## API | ||
> For more advanced usage scenarios please check use cases described in test specifications | ||
> For more advanced usage scenarios please check use cases described in test specification | ||
### getType | ||
> get type literal from action creator | ||
[> Advanced Usage](src/get-type.spec.ts) | ||
```ts | ||
function getType(actionCreator: AC<T>): T | ||
// AC<T> extends (...args: any[]) => { type: T } | ||
``` | ||
Examples: | ||
```ts | ||
const increment = createAction('INCREMENT'); | ||
const type: 'INCREMENT' = getType(increment); | ||
expect(type).toBe('INCREMENT'); | ||
// in reducer | ||
switch (action.type) { | ||
case getType(increment): | ||
return state + 1; | ||
default: return state; | ||
} | ||
``` | ||
--- | ||
### createAction | ||
> [> Advanced Usage](src/create-action.spec.ts) | ||
> creates action creator function with type helper | ||
[> Advanced Usage](src/create-action.spec.ts) | ||
```ts | ||
createAction(typeString, creatorFunction?) | ||
typeString: TS extends string, | ||
creatorFunction: (...args: any[]) => { type: TS, payload?: P, meta?: M, error?: boolean } | ||
return: ( | ||
(...args: any[]) => { type: TS, payload?: P, meta?: M, error?: boolean } | ||
) & { readonly type: TS } | ||
function createAction(typeString: T, creatorFunction?: CF): CF & { getType?(): T } | ||
// CF extends (...args: any[]) => { type: T, payload?: P, meta?: M, error?: boolean } | ||
``` | ||
@@ -180,20 +211,22 @@ | ||
const increment = createAction('INCREMENT'); | ||
// same as: | ||
// const increment = createAction('INCREMENT', () => ({ type: 'INCREMENT' })); | ||
expect(increment()).toEqual({ type: 'INCREMENT' }); | ||
expect(increment.type).toBe('INCREMENT'); | ||
expect(increment.getType!()).toBe('INCREMENT'); | ||
}); | ||
it('with payload', () => { | ||
const add = createAction('ADD', (type: 'ADD') => (amount: number) => | ||
({ type, payload: amount }), | ||
const add = createAction('ADD', | ||
(amount: number) => ({ type: 'ADD', payload: amount }), | ||
); | ||
expect(add(10)).toEqual({ type: 'ADD', payload: 10 }); | ||
expect(add.type).toBe('ADD'); | ||
expect(add.getType!()).toBe('ADD'); | ||
}); | ||
it('with payload and meta', () => { | ||
const notify = createAction('NOTIFY', (type: 'NOTIFY') => | ||
const notify = createAction('NOTIFY', | ||
(username: string, message: string) => ({ | ||
type, | ||
type: 'NOTIFY', | ||
payload: { message: `${username}: ${message}` }, | ||
@@ -204,8 +237,9 @@ meta: { username, message }, | ||
expect(notify('Piotr', 'Hello!')).toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
expect(notify.type).toBe('NOTIFY'); | ||
expect(notify('Piotr', 'Hello!')) | ||
.toEqual({ | ||
type: 'NOTIFY', | ||
payload: { message: 'Piotr: Hello!' }, | ||
meta: { username: 'Piotr', message: 'Hello!' }, | ||
}); | ||
expect(notify.getType!()).toBe('NOTIFY'); | ||
}); | ||
@@ -212,0 +246,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
64176
75
751
249