{"_id":"typesafe-actions","_rev":"67-8fb2f665f0a297f32f51468a1e2777c2","name":"typesafe-actions","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","dist-tags":{"latest":"5.1.0","next":"5.0.0-3"},"versions":{"0.0.1":{"name":"typesafe-actions","version":"0.0.1","description":"Typesafe Action Creators for Redux and Flux (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","prepublishOnlyDisabled":"yarn run clean && yarn run reinstall && yarn run check && yarn run test && yarn run build","check":"npm run lint & npm run tsc","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","build":"yarn run build:commonjs & yarn run build:module & yarn run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.6","@types/node":"6.0.94","jest-cli":"21.2.1","ts-jest":"21.2.2","ts-node":"3.3.0","tslib":"1.8.0","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","redux","flux"],"gitHead":"acf58151e2e675d81e7595a5837ebb4ed55e0c03","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@0.0.1","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-DDSL9UifXVIhka5BPK3R07h7y5K9G9Ykmj6XIvpiiWmpEGmyo0VwZc5LMlKinN5URP5XUBpqPi8ea6L5SHIMyg==","shasum":"4be5d3296e9842878a8c1dede69c439cc53efd3d","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-0.0.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDkG/iL+bPwOhM5tTwAkkipAcx8GI6W/f+cdbMhqn43ewIhAKi5BPC0hohsEJq2bdcetSblWuYnW0WZOdfZ+qEaIK4z"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-0.0.1.tgz_1514155760388_0.1900238855741918"},"directories":{}},"1.0.0-rc.1":{"name":"typesafe-actions","version":"1.0.0-rc.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslib":"1.8.1","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"be8c557a3444e6b1b2878db7c6c647f33181f635","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.0.0-rc.1","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-LhinKIl3oC1LP4EXnyTXXhU/KpTiNhj2/o07ik+C2nl9GfsNYwVsWF4xkaKxx20bVOIAInyGFh/sXS6MevdcyQ==","shasum":"170dd8501f6a444cfc0d286960c4693fe13410a4","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.0.0-rc.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDflQq+DDB4Ur0wtkoTGLysHQ3nKGbYHzHNmtPRKZ5lbwIgFSW0hPcN2f/xGcfwHQvxRtdQLgQNj6zVShdtfzYSgy8="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-1.0.0-rc.1.tgz_1514290965742_0.15476811886765063"},"directories":{}},"1.0.0":{"name":"typesafe-actions","version":"1.0.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslib":"1.8.1","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"1a96507082a61230dc4c9a2c8e966d6a4837ad09","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.0.0","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-L7wXh1nm07KjmE3nej0NJNHx5/Bc6Q7fIazfnqHkP97WLieEDBxXDCeMT98KSrtwbCneO14xQXokEPuW9sNG5w==","shasum":"9bd4b9e250399e818fd3dbf0235fa21972cda509","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.0.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDF32byG49x3dg0Q/jkmhrOCxxDCoEWQYJwFS5Ta/TuHgIhANxLY/Bi4m28zUuw82in+xOms6JU+duXhMk12FBaunty"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-1.0.0.tgz_1514454480840_0.7156120229046792"},"directories":{}},"1.1.0":{"name":"typesafe-actions","version":"1.1.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslib":"1.8.1","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"dc5fe7d18ce347e28055e17ab4e655edef76af40","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.1.0","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-0Am5C4O3XoWCzO/Fiequfn7j5okqdnvK2+AJK+t2Gtb2bS3gyiBqrFb7fUOYi+R60dob78qX2UAELvl3kmC/Tg==","shasum":"f98c815be0d37d8d1b22f28cc216677810c156e4","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.1.0.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH8aJtJJ5/GL1LK/oFer6t77uBXtuHOSMiYxeCCXVwdMAiEAw8a7xOzZM7EbcBlGwjbeVgiNM0SN8nL5EWRafKkpBPE="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-1.1.0.tgz_1514569641480_0.15591601957567036"},"directories":{}},"1.1.1":{"name":"typesafe-actions","version":"1.1.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslib":"1.8.1","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"b57cb5d5055e94c56b78b739cce6ba317493d817","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.1.1","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-WK5S3LwocNcUUcJv35pxuBYn8pr1Z+dEBIlZVHWBUw4hihGwwXVHNVvgElRw73sW4zrpRZNtCTTmurLKl+mU3g==","shasum":"c2d36a8f8df2fa6b5c8e4d17c6f74f9656ab4ef8","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.1.1.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDl93u48AjJBz2p8+XgtVCx8/XVIV2A+TkYgZ37zV1KNwIgMJYcnQ17qVou49CXlEMhIRwgxG6FpLSmhbAtiU2hv8E="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-1.1.1.tgz_1514881499497_0.9829690863844007"},"directories":{}},"1.1.2":{"name":"typesafe-actions","version":"1.1.2","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslib":"1.8.1","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"c899770ad4057de428423b7f8b079cb673704c5b","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.1.2","_npmVersion":"5.6.0","_nodeVersion":"6.11.5","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-4SparTfwBOWjegg89Ls5Ia0L6N8mXu7tb/REA5KYEfRohsLM9Uc8jtAa8bRAhtCg1cQJnvJJMjljI7dfu1JjVg==","shasum":"af88ede3ee254be425c3e0e02de11b182830ae48","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.1.2.tgz","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC5py/5lx9x6y4USO4auSjNvX/EKuShn/UWCaA7dVBzLgIgVy33s6fCx+XNoB7TAkB0qw4rHa0UKKPv95H7KNO3D0g="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions-1.1.2.tgz_1514882061508_0.4771103826351464"},"directories":{}},"1.2.0-rc.0":{"name":"typesafe-actions","version":"1.2.0-rc.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.0-rc"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"7773837182a0a69b07e4455c91d1c5f88e1b39a3","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.2.0-rc.0","_npmVersion":"5.7.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-NE62KlUYa+QlzdZrJmFNoyK5PGNxkZNq0j+kY6vv3CURig4Qwez+IwRV/pzCmh+MvynwXjD8SD0Y57VlhBMHFA==","shasum":"cea1d1effb5a0491c31de82647b58a4192e312f7","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.2.0-rc.0.tgz","fileCount":80,"unpackedSize":216652,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEoepjyLE02B3lrTJKWM+/EsGH4uf9QxhKx3Y4rS4++0AiEAlAOiCQP5b3saSHsl57y4OM/qanCzuYVTLj2v8o1PtlE="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.2.0-rc.0_1522058838351_0.2746865948801449"},"_hasShrinkwrap":false},"1.2.0-rc.1":{"name":"typesafe-actions","version":"1.2.0-rc.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.1"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"fe6ad96b8f29f27b39cbc5417f3cd6605276b8ae","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.2.0-rc.1","_npmVersion":"5.7.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-hxw6fOuGKeGqblB5QnDdnXG1CeqMfQi9tELSkj9kByJm9IhfkWtRjUGt6HZlvbooHNr5KfoYwRs6Wc7j/tocpg==","shasum":"5772521caa1e1b6c4f4073c920a1cf8cec2a1987","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.2.0-rc.1.tgz","fileCount":80,"unpackedSize":219599,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCjznnPL0/wJNCJ0iitPV954IloI7pJcP8oAIf2wkNYzgIhALpH0AqNPawFUpeMnos1Ef3Etz3tE2zwUAc+Nrjn2Nul"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.2.0-rc.1_1522189836311_0.5945071908850488"},"_hasShrinkwrap":false},"1.2.0-rc.2":{"name":"typesafe-actions","version":"1.2.0-rc.2","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.1"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"169100b0f26025e19813ece8cf896fa1afd0d0b5","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.2.0-rc.2","_npmVersion":"5.6.0","_nodeVersion":"9.2.1","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-gz3OG/42ggiYvS7LuBwQJKQoJPxLJVcFC+oued3diz1ekkzWPfoR+X9ozbfDeMH0PkylRogomq2nAfS05vDWTA==","shasum":"7058ccd9b85b29159e745262eb84095dddc3e723","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.2.0-rc.2.tgz","fileCount":80,"unpackedSize":218856,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDodXSTKPhU6m//ULkDLF0NC/y1DnNhtHrpWVChdczhkAIgaZVqkY0IHJ+URX3pJBoqWyZWvaf8jBWVydzD94eqUiM="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.2.0-rc.2_1522224089038_0.8756988834843449"},"_hasShrinkwrap":false},"1.2.0-rc.3":{"name":"typesafe-actions","version":"1.2.0-rc.3","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.1"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"47edeff332c766268500152d416e2f7d0d7a6409","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.2.0-rc.3","_npmVersion":"5.7.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-+WZLhJ6iOBZg5bRHZe9vUHUZiRsEigRZ1jWaQphsxWYnNf5UAsR3KR3KBkzJk9EDiSS4AccRC5fp3BkFRhrxTw==","shasum":"a884bbe4e39dead59b0d6fe30910d7a989426bad","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.2.0-rc.3.tgz","fileCount":80,"unpackedSize":219295,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCgm55G+HWG3adtaFmav4QO+FLjtIjAwmtMkpwgZjmkuwIhALoUzgx3tvbVgQPDk1D53J0xYX48uzyDYuZt4rqYk4yj"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.2.0-rc.3_1522761463850_0.5732218262219886"},"_hasShrinkwrap":false},"1.2.0-rc.4":{"name":"typesafe-actions","version":"1.2.0-rc.4","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.1"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"eb5ef0af68bde118c170ae71bd3f973505d95d39","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.2.0-rc.4","_npmVersion":"5.8.0","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-/SWugBr89OxznHpluA7hjCa3myl6XjLtxb5DAVXcXBWUbz3AmPqdkgHIZFOafmoN8sJ1F9UZpV8XvMgfUzBS5A==","shasum":"939cde44daf6697f75d73cb895603836142f48ac","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.2.0-rc.4.tgz","fileCount":80,"unpackedSize":222211,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGJ69iiKTsa+Kzqe1uxIKmESYMVKfW7TyyLkGCRdFJNWAiEAjaol9CGzuUwDvDnagVK4AlQbH0SMEjjx8YzkcPTTjfA="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.2.0-rc.4_1522799371951_0.08809090903609396"},"_hasShrinkwrap":false},"2.0.0-0":{"name":"typesafe-actions","version":"2.0.0-0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","format":"prettier --write 'src/**/*' 'README.md'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","prettier":"1.11.1","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslib":"1.9.0","tslint":"5.9.1","typescript":"2.8.1"},"prettier":{"printWidth":100,"trailingComma":"es5","singleQuote":true,"semi":true},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\n### _New API ([link to API docs](../../issues/22)) thanks to a new language feature ([conditional types](https://github.com/Microsoft/TypeScript/pull/21847)) coming to TypesScript in v2.8)_\n\nSimple functional API that's specifically designed to reduce **verbosity** (no explicit generic type arguments in the API, type inference FTW!)\nand **complexity** (retain \"type soundness\" and easily discriminate union types)\nof type annotations.\n\nThe main goal of this library is to limit the developers using the actions to incorrectly use them by strictly checking if the input parameters are correct. (for instance when you do **not** provide payload creator function, this means that your action creator will not accept any parameters and show error when someone will try to do that)\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Motivation](#motivation)\n* [Tutorial](#tutorial)\n* [API](#api)\n  * [`ActionsUnion`](#actionsunion)\n  * [`buildAction`](#buildaction)\n  * [`createAction`](#createaction)\n  * [`getType`](#gettype)\n  * [`isActionOf`](#isactionof)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\nFor NPM users\n\n```bash\n$ npm install --save typesafe-actions\n```\n\nFor Yarn users\n\n```bash\n$ yarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Motivation\n\nWhile trying to use [redux-actions](https://redux-actions.js.org/) with TypeScript I was dissapointed by it's \"unsoundness\" with static-typing [(more info here)](#redux-actions).\n\nMoreover **alternative solutions** in the wild have been either too verbose, used classes (which hinders readability) or was too \"explicitly typed\" instead of leveraging incredible type-inference (\"implicit types\").\n\n**That's why in `typesafe-actions` I created an API specifically designed to only use \"type-inference\" and provide a clean functional interface without a need to provide explicit generic type arguments, so that it feels like an expressive and idiomatic JavaScript.**\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo highlight the benefits of type inference leveraged in this solution, let me show you how to handle the most common use-cases found in Redux Architecture:\n\n### create union type of actions (a.k.a. `RootAction`)\n\n```ts\nimport { buildAction, ActionsUnion } from 'typesafe-actions';\n\nexport const counterActions = {\n  increment: buildAction('INCREMENT').empty(),\n  add: buildAction('ADD').payload<number>(),\n};\n\nexport const todosActions = { ... };\n\n// all actions merged for convenience\nexport type RootAction = ActionsUnion<typeof counterActions>;\n```\n\n> **PRO-TIP:** merge with third-party actions to create a complete Action Type\n\n```ts\nimport { RouterAction, LocationChangeAction } from 'react-router';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type AppAction = RootAction | ReactRouterAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### reducer switch cases\n\nUse `getType` function to reduce common boilerplate and discriminate union type of `RootAction` to a specific action.\n\n```ts\nimport { getType } from 'typesafe-actions';\n\nimport { RootState, RootAction } from '@src/redux';\nimport { add } from './actions';\n\nconst reducer = (state: RootState, action: RootAction) => {\n  switch (action.type) {\n    case getType(add):\n      return state + action.payload; // action is narrowed to a type of \"add\" action (payload: number)\n  ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### epics from `redux-observable`\n\nUse `isActionOf` function to filter actions and discriminate union type of `RootAction` to a specific action(s) down the stream.\n\n```ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { RootState, RootAction } from '@src/redux';\nimport { addTodo, toggleTodo } from './actions';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n...\n\n// with multiple actions\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .switchMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action (${action.type}: ${action.payload})`;\n...\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API\n\n### ActionsUnion\n\nWIP v2.0.0\n\n[⇧ back to top](#table-of-contents)\n\n### buildAction\n\nWIP v2.0.0\n\n[⇧ back to top](#table-of-contents)\n\n### createAction\n\n> create the action creator of a given function that contains private \"type\" metadata\n\n[> Advanced Usage](src/create-action.spec.ts)\n\n```ts\nfunction createAction(typeString: T, creatorFunction?: CF): CF;\n\n// CF extends (...args: any[]) => { type: T, payload?: P, meta?: M, error?: boolean }\n```\n\nExamples:\n\n```ts\n// no payload\nconst increment = createAction('INCREMENT');\n// same as:\n// const increment = createAction('INCREMENT', () => ({ type: 'INCREMENT' }));\n\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', (amount: number) => ({\n  type: 'ADD',\n  payload: amount,\n}));\n\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createAction('NOTIFY', (username: string, message: string) => ({\n  type: 'NOTIFY',\n  payload: { message: `${username}: ${message}` },\n  meta: { username, message },\n}));\n\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: { message: 'Piotr: Hello!' },\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action creator  \n> (It will infer literal type of action)\n\n[> Advanced Usage](src/get-type.spec.ts)\n\n```ts\nfunction getType(actionCreator: AC<T>): T;\n\n// AC<T> extends (...args: any[]) => { type: T }\n```\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> create the assert function for specified action creator(s) - resulting function will then assert (true/false) maching actions  \n> (it will discriminate union type to specified action creator(s))\n\n[> Advanced Usage](src/is-action-of.spec.ts)\n\n```ts\nfunction isActionOf(actionCreator: AC<T>): (action: any) => action is T;\nfunction isActionOf(actionCreators: Array<AC<T>>): (action: any) => action is T;\n\n// AC<T> extends (...args: any[]) => T\n```\n\nExamples:\n\n```ts\n// in epics, with single action\nimport { addTodo } from './actions';\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n...\n\n// with multiple actions\nimport { addTodo, toggleTodo } from './actions';\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n...\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out the differences compared to other solutions.\n\n### `redux-actions`\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### no payload\n\n* redux-actions\n\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// const notify1: () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` notice excess \"nullable\" properties `payload` and `error`, also the action `type` property is widened to string (🐼 is really sad!)\n\n* typesafe-actions\n\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// const notify1: () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no nullable types, only the data that is really there, also the action \"type\" property is correct narrowed to literal type (great success!)\n\n#### with payload\n\n* redux-actions\n\n```ts\nconst notify2 = createAction('NOTIFY', (username: string, message?: string) => ({\n  message: `${username}: ${message || ''}`,\n}));\n// resulting type:\n// const notify2: (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> notice the missing optional `message` parameter in resulting function also `username` param name is changed to `t1`, action `type` property is widened to string and incorrect nullable properties\n\n* typesafe-actions\n\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    type: 'NOTIFY'\n    payload: { message: `${username}: ${message || ''}` },\n  })\n)\n// resulting type:\n// const notify2: (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` retain complete type soundness\n\n#### with payload and meta\n\n* redux-actions\n\n```ts\nconst notify3 = createAction(\n  'NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || ''}`,\n  }),\n  (username: string, message?: string) => ({ username, message })\n);\n// resulting type:\n// const notify3: (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> notice complete loss of arguments arity and types in resulting function, moreover action `type` property is again widened to string with nullable `payload` and `error`\n\n* typesafe-actions\n\n```ts\nconst notify3 = createAction('NOTIFY', (username: string, message?: string) => ({\n  type: 'NOTIFY',\n  payload: { message: `${username}: ${message || ''}` },\n  meta: { username, message },\n}));\n// resulting type:\n// const notify3: (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` makes 🐼 happy once again\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"3451d6f70eb7e886cff95f94dc289ec5eb193cb9","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.0-0","_npmVersion":"5.8.0","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-cmOG8re6W9bYooDlkoU/EixUnj2PjU0B/R31tsa0Fv8mOi9FeGA1rGs8mi6N52tVz3M8XKHePCaCusyap45ynQ==","shasum":"790834f58f6c1697b49ec9aae7c29d19d8bc96f2","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.0-0.tgz","fileCount":89,"unpackedSize":95221,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBEAZUtBp/kTCoEWte/XPs4wxcHJP0r1yqqjFWrjBZ78AiAYGTNQf4yI1nTiWZvaxPwVAjhDminY+kxQeMOGDs4ewQ=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.0-0_1522867572694_0.5956117796312517"},"_hasShrinkwrap":false},"2.0.0-1":{"name":"typesafe-actions","version":"2.0.0-1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","prelint":"prettier --write 'src/**/*' 'README.md'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{"tslib":"1.9.0"},"devDependencies":{"@types/jest":"22.2.2","husky":"0.14.3","jest":"22.4.3","prettier":"1.11.1","redux":"^3.7.2","ts-jest":"22.4.2","ts-node":"5.0.1","tslint":"5.9.1","typescript":"2.8.1"},"prettier":{"printWidth":100,"trailingComma":"es5","singleQuote":true,"semi":true},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\n### _New API ([link to API docs](../../issues/22)) thanks to a new language feature ([conditional types](https://github.com/Microsoft/TypeScript/pull/21847)) coming to TypesScript in v2.8)_\n\nSimple functional API that's specifically designed to reduce **verbosity** (no explicit generic type arguments in the API, type inference FTW!)\nand **complexity** (retain \"type soundness\" and easily discriminate union types)\nof type annotations.\n\nThe main goal of this library is to limit the developers using the actions to incorrectly use them by strictly checking if the input parameters are correct. (for instance when you do **not** provide payload creator function, this means that your action creator will not accept any parameters and show error when someone will try to do that)\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Motivation](#motivation)\n* [Tutorial](#tutorial)\n* [API](#api)\n  * [`ActionsUnion`](#actionsunion)\n  * [`buildAction`](#buildaction)\n  * [`createAction`](#createaction)\n  * [`getType`](#gettype)\n  * [`isActionOf`](#isactionof)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\nFor NPM users\n\n```bash\n$ npm install --save typesafe-actions\n```\n\nFor Yarn users\n\n```bash\n$ yarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Motivation\n\nWhile trying to use [redux-actions](https://redux-actions.js.org/) with TypeScript I was dissapointed by it's \"unsoundness\" with static-typing [(more info here)](#redux-actions).\n\nMoreover **alternative solutions** in the wild have been either too verbose, used classes (which hinders readability) or was too \"explicitly typed\" instead of leveraging incredible type-inference (\"implicit types\").\n\n**That's why in `typesafe-actions` I created an API specifically designed to only use \"type-inference\" and provide a clean functional interface without a need to provide explicit generic type arguments, so that it feels like an expressive and idiomatic JavaScript.**\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo highlight the benefits of type inference leveraged in this solution, let me show you how to handle the most common use-cases found in Redux Architecture:\n\n### create union type of actions (a.k.a. `RootAction`)\n\n```ts\nimport { buildAction, ActionsUnion } from 'typesafe-actions';\n\nexport const counterActions = {\n  increment: buildAction('INCREMENT').empty(),\n  add: buildAction('ADD').payload<number>(),\n};\n\nexport const todosActions = { ... };\n\n// all actions merged for convenience\nexport type RootAction = ActionsUnion<typeof counterActions>;\n```\n\n> **PRO-TIP:** merge with third-party actions to create a complete Action Type\n\n```ts\nimport { RouterAction, LocationChangeAction } from 'react-router';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type AppAction = RootAction | ReactRouterAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### reducer switch cases\n\nUse `getType` function to reduce common boilerplate and discriminate union type of `RootAction` to a specific action.\n\n```ts\nimport { getType } from 'typesafe-actions';\n\nimport { RootState, RootAction } from '@src/redux';\nimport { add } from './actions';\n\nconst reducer = (state: RootState, action: RootAction) => {\n  switch (action.type) {\n    case getType(add):\n      return state + action.payload; // action is narrowed to a type of \"add\" action (payload: number)\n  ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### epics from `redux-observable`\n\nUse `isActionOf` function to filter actions and discriminate union type of `RootAction` to a specific action(s) down the stream.\n\n```ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { RootState, RootAction } from '@src/redux';\nimport { addTodo, toggleTodo } from './actions';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n...\n\n// with multiple actions\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .switchMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action (${action.type}: ${action.payload})`;\n...\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API\n\n### ActionsUnion\n\nWIP v2.0.0\n\n[⇧ back to top](#table-of-contents)\n\n### buildAction\n\nWIP v2.0.0\n\n[⇧ back to top](#table-of-contents)\n\n### createAction\n\n> create the action creator of a given function that contains private \"type\" metadata\n\n[> Advanced Usage](src/create-action.spec.ts)\n\n```ts\nfunction createAction(typeString: T, creatorFunction?: CF): CF;\n\n// CF extends (...args: any[]) => { type: T, payload?: P, meta?: M, error?: boolean }\n```\n\nExamples:\n\n```ts\n// no payload\nconst increment = createAction('INCREMENT');\n// same as:\n// const increment = createAction('INCREMENT', () => ({ type: 'INCREMENT' }));\n\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', (amount: number) => ({\n  type: 'ADD',\n  payload: amount,\n}));\n\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createAction('NOTIFY', (username: string, message: string) => ({\n  type: 'NOTIFY',\n  payload: { message: `${username}: ${message}` },\n  meta: { username, message },\n}));\n\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: { message: 'Piotr: Hello!' },\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action creator  \n> (It will infer literal type of action)\n\n[> Advanced Usage](src/get-type.spec.ts)\n\n```ts\nfunction getType(actionCreator: AC<T>): T;\n\n// AC<T> extends (...args: any[]) => { type: T }\n```\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> create the assert function for specified action creator(s) - resulting function will then assert (true/false) maching actions  \n> (it will discriminate union type to specified action creator(s))\n\n[> Advanced Usage](src/is-action-of.spec.ts)\n\n```ts\nfunction isActionOf(actionCreator: AC<T>): (action: any) => action is T;\nfunction isActionOf(actionCreators: Array<AC<T>>): (action: any) => action is T;\n\n// AC<T> extends (...args: any[]) => T\n```\n\nExamples:\n\n```ts\n// in epics, with single action\nimport { addTodo } from './actions';\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n...\n\n// with multiple actions\nimport { addTodo, toggleTodo } from './actions';\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n...\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out the differences compared to other solutions.\n\n### `redux-actions`\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### no payload\n\n* redux-actions\n\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// const notify1: () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` notice excess \"nullable\" properties `payload` and `error`, also the action `type` property is widened to string (🐼 is really sad!)\n\n* typesafe-actions\n\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// const notify1: () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no nullable types, only the data that is really there, also the action \"type\" property is correct narrowed to literal type (great success!)\n\n#### with payload\n\n* redux-actions\n\n```ts\nconst notify2 = createAction('NOTIFY', (username: string, message?: string) => ({\n  message: `${username}: ${message || ''}`,\n}));\n// resulting type:\n// const notify2: (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> notice the missing optional `message` parameter in resulting function also `username` param name is changed to `t1`, action `type` property is widened to string and incorrect nullable properties\n\n* typesafe-actions\n\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    type: 'NOTIFY'\n    payload: { message: `${username}: ${message || ''}` },\n  })\n)\n// resulting type:\n// const notify2: (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` retain complete type soundness\n\n#### with payload and meta\n\n* redux-actions\n\n```ts\nconst notify3 = createAction(\n  'NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || ''}`,\n  }),\n  (username: string, message?: string) => ({ username, message })\n);\n// resulting type:\n// const notify3: (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> notice complete loss of arguments arity and types in resulting function, moreover action `type` property is again widened to string with nullable `payload` and `error`\n\n* typesafe-actions\n\n```ts\nconst notify3 = createAction('NOTIFY', (username: string, message?: string) => ({\n  type: 'NOTIFY',\n  payload: { message: `${username}: ${message || ''}` },\n  meta: { username, message },\n}));\n// resulting type:\n// const notify3: (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` makes 🐼 happy once again\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"4a038cf6c57c0875ca1a9a94acca565d0887e960","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.0-1","_npmVersion":"5.8.0","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-YuejAidhCQ8ogJMty/viF4dagTKKgCTDYearFT7X0uSOZf6pCeZJR8RfJb12UyMjHunmkC8m+BBuWEmO/GI3ug==","shasum":"b6a1aad1abfd3798342d66778b61a68aa7b14d56","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.0-1.tgz","fileCount":90,"unpackedSize":225987,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCsiMkF2YpNFJ1a2a1P84KV0n1I2ExJmYwAKdmACKdMCgIhAJJYyjsxZJzl2q6qSKi3GO04L5p9E7TELFrLMAQn9OZm"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.0-1_1522955275155_0.28831597217247995"},"_hasShrinkwrap":false},"1.1.3":{"name":"typesafe-actions","version":"1.1.3","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"es5-commonjs/index.d.ts","main":"es5-commonjs/index.js","module":"es5-module/index.js","jsnext:main":"jsnext/index.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && yarn install","clean":"rm -rf es5-commonjs/ es5-module/ jsnext/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","build":"npm run build:commonjs & npm run build:module & npm run build:jsnext","build:commonjs":"rm -rf es5-commonjs/ && tsc -p . --outDir es5-commonjs/","build:module":"rm -rf es5-module/ && tsc -p . --outDir es5-module/ -m 'ES2015'","build:jsnext":"rm -rf jsnext/ && tsc -p . --outDir jsnext/ -t 'ES2015'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","precommit":"npm run lint","prepush":"npm run test","prepublishOnly":"npm run clean && npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{"tslib":"1.8.1"},"devDependencies":{"@types/jest":"21.1.9","@types/node":"6.0.95","husky":"0.14.3","jest-cli":"22.0.4","redux":"^3.7.2","ts-jest":"22.0.0","ts-node":"4.1.0","tslint":"5.8.0","typescript":"2.6.2"},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"gitHead":"9c530aa9e649fb5337372b21fc5b509220d0fc00","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@1.1.3","_npmVersion":"5.8.0","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-EA0hUhipiHWlZLaOv6k5UxunGVBf0y+SsIuodC3d5qxwcJ7CHPW/gw54BQKSZ7jW7gAEa/YAEdUgIP+z/iN1iQ==","shasum":"ef4dde7042ce4b8ba0900736d92331bbef8b5737","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-1.1.3.tgz","fileCount":58,"unpackedSize":55329,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa8qm5CRA9TVsSAnZWagAAk6wP/0B43zwRnLIwxpqq0SlY\n93htNS6TOLPwpeIQj4TqUTvJGuUONP5Kt8QFccH8oMZlRIBCtArHKw2lDaaD\n5k78N70arh+L3TzO7r0u9yf4G6BMxwFAKI9tgBgrD/on6VW7+IYx1dtn23hM\nmURRPUqmtMM6IpCjuM4qoL8Rp1tA3E1sZkOL0yP6UM0jgIk+cw8e+LaH9Ozo\nU2YahgMClHzZgsMV2BorW7G4+4LY1xD8RFxXVJcIYbZLZDbJsgs+vPa/Q1OD\nNDnhbyKWfjzgnIHc6H8FEFEhNmV9D4paLua8e7uFOtcKTdThQyMiTbR+K5sq\nk4sI/2gwO+DDYT6/Gl2g3PiVBfCMljq7JsvYOc7GiEbMSHS7x4Bko4xr4Zix\nhhW9iMnJ7WwrBm+/mNrBvUg9pd94zFDgc1ffPPtogYUCpWYxBd0vdgtN9UXx\nL0Jf/5yf7JcdXDITOloRYC7vWQ2DB31k8DgiXESY1g4B2xFqaiMuP9PW2BsH\n2aoW+uS4CezxPu27+JMeTJYBNW77ZkTTIABPqToVBFmFJ8wBGPJIq+BDCSjU\n6uZs/2WNhAap3GwhFG4F7087wj9CnaeAs6unT0yh8NLAGrX8xRxs1ob6NM2h\n5sZigJ62wViUuv07U6lUna33wl1QHLUDgLc7Vzi3fwxzFSMQyhDpcXjNBqx5\nUNxU\r\n=op1n\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIARSDoimvBlCsCDbeZPvx29CP8HXZtUA3IDgmbuyg+gDAiEA/tRJ73DqVlEzy7YUSbCpZUKAu0KZkcgYxAaZcwPXA+A="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_1.1.3_1525852600632_0.3135381337051122"},"_hasShrinkwrap":false},"2.0.0-test.0":{"name":"typesafe-actions","version":"2.0.0-test.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && npm install","clean":"rm -rf dist/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prelint":"prettier --write 'src/**/*'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","prepush":"npm run lint & npm run test","prepublishOnly":"npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{"tslib":"1.9.0"},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","redux":"4.0.0","rollup":"0.58.2","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.5","tslint":"5.10.0","typescript":"2.8.3"},"prettier":{"printWidth":80,"trailingComma":"es5","singleQuote":true,"semi":true},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\nSimple functional API that's specifically designed to reduce types **verbosity** (especially maintainability concerns)\nand **complexity** (powerful helpers hiding types complexity).\n\n### Goals\n\n* complete type-safety for payload operations in reducer with switch cases and conditional statements (TODO: [link])\n* easy discrimination of union types for `redux-observable` epics but also in any other functional api with `filter` method (TODO: [link])\n* strictly check arguments of given payload when invoking action creators in view layer (TODO: [link])\n\n### Features\n\n* __small and focused__ - (Bundle size: 2.72 KB, Gzipped size: 879 B)\n* __secure__ - no external dependencies for browser (`tslib` in case of cjs/esm modules)\n* __tested__ - complete test-suite with tests for type soundness\n\n## Motivation\n\nWhen I was first trying to use [redux-actions](https://redux-actions.js.org/) with TypeScript I was intimidated by incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here to read more detailed comparison)](#redux-actions).\n\nMoreover alternative solutions in the wild have been either **too verbose because of excess type annotations** (primary maintainability concern) or **used classes** (hinders readability and enforce to use a **new** keyword 😱).\n\nThat's why I created `typesafe-actions` with the core idea to lean on incredible **type-inference** 💪. to reduce the maintainability costs of type signatures and also to make it feel like simple idiomatic JavaScript because of reduced explicit types annotations to minimum.\\*\\*\n\n**From v2.0 we added a complementary API leveraging generic type arguments to provide a very concise and expressive way to use a \"bag object\" as payload argument and cut the boilerplate to one-liner**\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Tutorial](#tutorial)\n* [API](#api)\n  * [`ActionsUnion`](#actionsunion) (RootAction type-helper)\n  * [`action`](#action)\n  * [`createAction`](#createaction)\n  * [`createStandardAction`](#createstandardaction)\n  * [`createAsyncAction`](#createasyncaction)\n  * [`getType`](#gettype)\n  * [`isActionOf`](#isactionof)\n  * [`isOfType`](#isoftype)\n* [Migration Guide](#migration-guide)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install --save typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the power of **type-safety** provided by this library, let me show you how to build a typical todo app in a type-safe Redux Architecture:\n\nHere is a link to completed todo-app in codesandbox: [TODO: link]\n\n### - the actions (a.k.a. `RootAction`)\n\n```ts\n// counter-actions.ts\nimport { createStandardAction, ActionsUnion } from 'typesafe-actions';\n\nexport const add = createStandardAction('todos/ADD')<Todo>();\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n\n// merge all actions object for convenience\nimport * as todos from './todos-actions';\nimport * as toasts from './toasts-actions';\n\nexport const actions = { todos, toasts };\n// then you can use: dispatch(actions.todos.add({...}))\n\nexport type RootAction = ActionsUnion<typeof actions>;\n```\n\n> **PRO-TIP:** merge with third-party action types to model a complete representation of all possible actions at runtime\n\n```ts\n// example of including `react-router` action types\nimport { RouterAction, LocationChangeAction } from 'react-router';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type AppAction = RootAction | ReactRouterAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - reducer switch cases\n\nUse `getType` function to reduce boilerplate and mitigate the trouble of importing \"type constants\" across the application layers (the principle is to use action creators instead).\nMoreover **it's a type-guard** so it will discriminate union type of `RootAction` to a specific action withing a code block.\n\n```ts\nimport { getType } from 'typesafe-actions';\n\nimport { RootAction } from '../types';\nimport { add } from './todos-actions';\n\nconst reducer = (state: Todo[] = [], action: RootAction) => {\n  switch (action.type) {\n    case getType(add): // TIP: if you prefer you could still use a regular \"type constants\" here\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - composite actions for async network requests\n\n```ts\n// WIP\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - side-effects with `redux-observable`\n\nUse `isActionOf` function to use action creator function to filter actions and to narrow (discriminate) union type of `RootAction` to a specific action(s) down the stream.\n\n```ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { add, toggle } from './todos-actions';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isActionOf(add))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n```\n\n> **PRO-TIP:** it works with multiple actions in array\n```ts\nconst logTodoAction: Epic<RootAction, RootState, Services> =\n  (action$, store, { logService }) => action$\n    .filter(isActionOf([add, toggle]))\n    .do((action) => { // action is narrowed as:\n      // { type: \"todos/ADD\", payload: Todo } | { type: \"todos/TOGGLE\", payload: string }\n      ...\n```\n\nAlternatively if you prefer to use type constants there is a `isOfType` function to use with constants instead of action creators \n\n```ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { ADD } from './todos-types';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isTypeOf(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      ...\n```\n\n> **PRO-TIP:** you can use it for conditional statements\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API\n\n### ActionsUnion\n\n> powerful type helper that will infer union type from various nested objects or arrays with action creators\n\n```ts\nimport { ActionsUnion } from 'typesafe-actions';\n\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    }\n  }\n};\n\nexport type RootAction = ActionsUnion<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### action\n\n> simple action factory function, to create typed action\n\n```ts\nfunction action(type: T, payload?: P, meta?: M): { type: T, payload?: P, meta?: M }\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string } }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAction\n\n> create the action creator of a typesafe compatible action\n\n```ts\nfunction createAction(type: T, creatorHandler?: (actionCallback: (payload, meta) => Action<T>) => AC<T>): AC<T>;\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// no payload\nconst increment = createAction('INCREMENT');\n// same as:\n// const increment = createAction('INCREMENT', actionCallback => {\n//   return () => actionCallback());\n// });\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', actionCallback => {\n  return (amount: number) => actionCallback(amount);\n});\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createAction('NOTIFY', actionCallback => {\n  return (username: string, message: string) => actionCallback(\n    { message: `${username}: ${message}` },\n    { username, message }\n  );\n});\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: { message: 'Piotr: Hello!' },\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createStandardAction\n\n> simple creator compatible with \"Flux Standard Action\" to reduce boilerplate and enforce convention\n\n```ts\nfunction createAction(type: T): <P, M>() => AC<T, P, M>;\nfunction createAction(type: T): { map: (arg: any) => AC<T, P, M> };\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// no payload\nconst increment = createStandardAction('INCREMENT')<void>();\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createStandardAction('ADD')<number>();\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createStandardAction('NOTIFY').map(\n  ({ username, message }}: Notification) => ({\n    payload: `${username}: ${message || ''}`,\n    meta: { username, message }, \n  })\n);\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: 'Piotr: Hello!',\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAsyncAction\n\n> create a composite action creator containing three action handlers for async flow (e.g. network request - request/success/failure)\n\n```ts\nfunction createAsyncAction(requestType: T1, successType: T2, failureType: T3): <P1, P2, P3>() => {\n  request: AC<T1, P1>,\n  success: AC<T2, P2>,\n  failure: AC<T3, P3>,\n};\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchUserTypes = createAsyncAction(\n  'FETCH_USER_REQUEST',\n  'FETCH_USER_SUCCESS',\n  'FETCH_USER_FAILURE'\n)<void, User, Error>();\n\nconst requestResult = fetchUserTypes.request();\nexpect(requestResult).toEqual({ type: 'FETCH_USER_REQUEST' });\n\nconst successResult =\n  fetchUserTypes.success({ firstName: 'Piotr', lastName: 'Witek' });\nexpect(successResult).toEqual({\n  type: 'FETCH_USER_SUCCESS',\n  payload: { firstName: 'Piotr', lastName: 'Witek' },\n});\n\nconst failureResult = fetchUserTypes.failure(Error('Failure reason'));\nexpect(failureResult).toEqual({\n  type: 'FETCH_USER_FAILURE',\n  payload: Error('Failure reason'),\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action creator  \n> contains properly narrowed literal type\n\n```ts\nfunction getType(actionCreator: (...args) => T): T\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> (curried assert function) Check if action is an instance of given action creator(s)\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator: ActionCreator<T>, action: any): action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>, action: any): action is T\n// or curried function\nisActionOf(actionCreator: ActionCreator<T>): (action: any) => action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo } from './todos-actions';\n\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n\n// epics with multiple actions\nimport { addTodo, toggleTodo } from './todos-actions';\n\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n\n// conditionals where you need a type guard\nimport { addTodo } from './actions';\n\nif(isActionOf(addTodo, action)) {\n  operationThatNeedsPayload(action.payload) // action is asserted as: { type: \"ADD_TODO\", payload: string }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isOfType\n\n> (curried assert function) Check if action type equals given type constant\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisOfType(type: T, action: any): action is Action<T>\n// or curried function\nisOfType(type: T): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD } from './todos-types';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isOfType(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n\n// conditionals where you need a type guard\nimport { ADD } from './todos-types';\n\nif(isOfType(ADD, action)) {\n  return functionThatAcceptsTodo(action.payload) // action: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guide\n\n### v1.x.x to v2.x.x\n\n```ts\nconst deprecatedApi = createActionDeprecated('GET_TODO',\n  (token: string, id: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: token,\n  })\n);\n\nconst getTodoSimple = (token: string, id: string) => action('GET_TODO', id, token);\n\nconst getTodoVariadic = createAction('GET_TODO', action => {\n  return (id: string, token: string) => action(id, token);\n});\n\nconst getTodoStandard = createStandardAction('GET_TODO')<{ id: string; token: string; }>();\n\nconst getTodoStandardMap = createStandardAction('GET_TODO').map(\n  ({ id, token }: { id: string; token: string; }) => ({\n    payload: id,\n    meta: token,\n  })\n);\n```\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common action-creators variants (type only, with payload, with payload and meta)\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### - type only (no payload)\n\n```ts\n/**\n * redux-actions\n */\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination would not be possible) (🐼 is really sad!)\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types, only the data that is really there, also the action \"type\" property is containing precise literal type\n\n#### - with payload\n\n```ts\n/**\n * redux-actions\n */\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` param name is changed to some generic `t1`, literal type of `type` property is lost again and `payload` is nullable because of broken inference\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` still retain very precise resulting type\n\n#### - with payload and meta\n\n```ts\n/**\n * redux-actions\n */\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a complete loss of arguments arity with falling back to `any` type with all the remaining issues as before\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type (🐼 is impressed by completely type-safe results)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"02da5687b3542b4fd7d0dd67f68f3c027a64dc54","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.0-test.0","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-rkFf2OY5MpZ96F+Y03SPZDVSDFW2+hfU0ug2u+Sx1UbH2iIlADb+MRPh1e5s2+sRO2qrY/ga4mTW9ORKoNcLVQ==","shasum":"8fdc1e9c6eefb0b18734b8d716c89317f982a75e","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.0-test.0.tgz","fileCount":44,"unpackedSize":131423,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa9ZwYCRA9TVsSAnZWagAA9p0P/iijrfoBKPU0aBsy+T0J\nbpGwkmozqXa/AAIKPvU/ORiC62zkRZoIYr2EbgMAbvjF0BHTAKplE0DAUqCR\nP4Moc16jHC8PayaoY7SMr2JJDuZbd+iTR9NxEFTVfBduktxS6JuOeatEOkHg\nmdT+wqc/QRLoIEcV38XvQnjsAW+ITf8vtOIEOV0IeQxFYWsfzhfmVd/Ahaj5\ngFJE9UvbNV/QAMn9j7rNbEe97+pVpkY0XM7e4FYZcWm2b13Ly8aAGgH7Ofrj\n6ph+KhUsubrBuLUF3vi6sSwG26lBUOIBl4lyT30O60/TWdv70DRr89TwCVzT\nWatD7pD1WM0dhkCtfD2y7GjBsokcDZT0+mfCUZ4ilraOdtEymalqrdqcujxE\ntmxDT66TaspWkIih094QfwyiCQl1HT1dg9Hb4uSpjfFPQVnK4T8y7ftB6yMc\nHmsNFskwvo+kVn3P9g+0XLb0EzdPJ/bhGmcqtKOEYn9W4U9+VG8hZnhLYG0B\nk8NBJB1c+eDGTQE5Ra09Hjar4fng2VsSgdlFJv7/WaLaYrB7sOyi/EC1HYqP\nRh77a+7P6dL5vHZjRaoc4nu5XrSOFzkel9CtXJ5nDtAU6CB4EJhg9htTy9LL\nBEPFsv6RdPAjY5Mm5cMwC5vOr6vd5I/tQoGLlQlalhWw3LVz8mn/DlhZ5LbC\nAJuH\r\n=7e92\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICxgfmrUaO7Lsw+DtfuA5w8trCzM0PNrh8kD1TVp4HOMAiEA0bfHWfFTQ4uNIFcHESHxIwNSUa3j56vv4S5tPD8bysk="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.0-test.0_1526045719882_0.7508941689935413"},"_hasShrinkwrap":false},"2.0.0-rc.0":{"name":"typesafe-actions","version":"2.0.0-rc.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && npm install","clean":"rm -rf dist/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prelint":"prettier --write 'src/**/*'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","prepush":"npm run lint & npm run test","prepublishOnly":"npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{"tslib":"1.9.0"},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","redux":"4.0.0","rollup":"0.58.2","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.5","tslint":"5.10.0","typescript":"2.8.3"},"prettier":{"printWidth":80,"trailingComma":"es5","singleQuote":true,"semi":true},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\n> #### Reference implementation of Todo App with `typesafe-actions`: https://codesandbox.io/s/v8k8y3j837\n\nSimple functional API that's specifically designed to reduce types **verbosity** (especially maintainability concerns)\nand **complexity** (thanks to powerful helpers).\n\n### Goals\n\n* complete type-safety for payload operations in reducer with switch cases and conditional statements ([docs](#reducer-switch-cases))\n* simplify handling async flow of network requests with multistep composite actions ([docs](#handling-async-flow-of-network-requests))\n* simplify discrimination of union types for `redux-observable` epics but works as well for any other libraries thanks to wide set of helpers ([docs](#side-effects-with-redux-observable))\n* strictly check arguments of given payload when invoking action creators in view layer (TODO: [link])\n\n### Features\n\n* __small and focused__ - (Bundle size: 2.72 KB, Gzipped size: 879 B)\n* __secure__ - no external dependencies for browser (`tslib` in case of cjs/esm modules)\n* __tested__ - complete test-suite with tests for type soundness\n\n## Motivation\n\nWhen I was first trying to use [redux-actions](https://redux-actions.js.org/) with TypeScript I was intimidated by incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here to read more detailed comparison)](#redux-actions).\n\nMoreover alternative solutions in the wild have been either **too verbose because of excess type annotations** (primary maintainability concern) or **used classes** (hinders readability and enforce to use a **new** keyword 😱).\n\nThat's why I created `typesafe-actions` with the core idea to lean on incredible **type-inference** 💪. to reduce the maintainability costs of type signatures and also to make it feel like simple idiomatic JavaScript because of reduced explicit types annotations to minimum.\\*\\*\n\n**From v2.0 we added a complementary API leveraging generic type arguments to provide a very concise and expressive way to use a \"bag object\" as payload argument and cut the boilerplate to one-liner**\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Tutorial](#tutorial)\n* [API](#api)\n  * [`ActionsUnion`](#actionsunion) (RootAction type-helper)\n  * [`action`](#action)\n  * [`createAction`](#createaction)\n  * [`createStandardAction`](#createstandardaction)\n  * [`createAsyncAction`](#createasyncaction)\n  * [`getType`](#gettype)\n  * [`isActionOf`](#isactionof)\n  * [`isOfType`](#isoftype)\n* [Migration Guide](#migration-guide)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install --save typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the power of **type-safety** provided by this library, let me show you how to build a typical todo app in a type-safe Redux Architecture:\n\nHere is a link to completed todo-app in codesandbox: [TODO: link]\n\n### - the actions (a.k.a. `RootAction`)\n\n```ts\n// counter-actions.ts\nimport { createStandardAction, ActionsUnion } from 'typesafe-actions';\n\nexport const add = createStandardAction('todos/ADD')<Todo>();\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n\n// merge all actions object for convenience\nimport * as todos from './todos-actions';\nimport * as toasts from './toasts-actions';\n\nexport const actions = { todos, toasts };\n// then you can use: dispatch(actions.todos.add({...}))\n\nexport type RootAction = ActionsUnion<typeof actions>;\n```\n\n> **PRO-TIP:** merge with third-party action types to model a complete representation of all possible actions at runtime\n\n```ts\n// example of including `react-router` action types\nimport { RouterAction, LocationChangeAction } from 'react-router';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type AppAction = RootAction | ReactRouterAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - reducer switch cases\n\nUse `getType` function to reduce boilerplate and mitigate the trouble of importing \"type constants\" across the application layers (the principle is to use action creators instead).\nMoreover **it's a type-guard** so it will discriminate union type of `RootAction` to a specific action withing a code block.\n\n```ts\nimport { getType } from 'typesafe-actions';\n\nimport { RootAction } from '../types';\nimport { add } from './todos-actions';\n\nconst reducer = (state: Todo[] = [], action: RootAction) => {\n  switch (action.type) {\n    case getType(add): // TIP: if you prefer you could still use a regular \"type constants\" here\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - handling async flow of network requests\n\n```ts\n// WIP\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - side-effects with `redux-observable`\n\nUse `isActionOf` function to use action creator function to filter actions and to narrow (discriminate) union type of `RootAction` to a specific action(s) down the stream.\n\n```ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { add, toggle } from './todos-actions';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isActionOf(add))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n```\n\n> **PRO-TIP:** it works with multiple actions in array\n```ts\nconst logTodoAction: Epic<RootAction, RootState, Services> =\n  (action$, store, { logService }) => action$\n    .filter(isActionOf([add, toggle]))\n    .do((action) => { // action is narrowed as:\n      // { type: \"todos/ADD\", payload: Todo } | { type: \"todos/TOGGLE\", payload: string }\n      ...\n```\n\nAlternatively if you prefer to use type constants there is a `isOfType` function to use with constants instead of action creators \n\n```ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { ADD } from './todos-types';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isTypeOf(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      ...\n```\n\n> **PRO-TIP:** you can use it for conditional statements\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API\n\n### ActionsUnion\n\n> powerful type helper that will infer union type from various nested objects or arrays with action creators\n\n```ts\nimport { ActionsUnion } from 'typesafe-actions';\n\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    }\n  }\n};\n\nexport type RootAction = ActionsUnion<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### action\n\n> simple action factory function, to create typed action\n\n```ts\nfunction action(type: T, payload?: P, meta?: M): { type: T, payload?: P, meta?: M }\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string } }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAction\n\n> create the action creator of a typesafe compatible action\n\n```ts\nfunction createAction(type: T, creatorHandler?: (actionCallback: (payload, meta) => Action<T>) => AC<T>): AC<T>;\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// no payload\nconst increment = createAction('INCREMENT');\n// same as:\n// const increment = createAction('INCREMENT', actionCallback => {\n//   return () => actionCallback());\n// });\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', actionCallback => {\n  return (amount: number) => actionCallback(amount);\n});\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createAction('NOTIFY', actionCallback => {\n  return (username: string, message: string) => actionCallback(\n    { message: `${username}: ${message}` },\n    { username, message }\n  );\n});\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: { message: 'Piotr: Hello!' },\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createStandardAction\n\n> simple creator compatible with \"Flux Standard Action\" to reduce boilerplate and enforce convention\n\n```ts\nfunction createAction(type: T): <P, M>() => AC<T, P, M>;\nfunction createAction(type: T): { map: (arg: any) => AC<T, P, M> };\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// no payload\nconst increment = createStandardAction('INCREMENT')<void>();\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createStandardAction('ADD')<number>();\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createStandardAction('NOTIFY').map(\n  ({ username, message }}: Notification) => ({\n    payload: `${username}: ${message || ''}`,\n    meta: { username, message }, \n  })\n);\nexpect(notify('Piotr', 'Hello!')).toEqual({\n  type: 'NOTIFY',\n  payload: 'Piotr: Hello!',\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAsyncAction\n\n> create a composite action creator containing three action handlers for async flow (e.g. network request - request/success/failure)\n\n```ts\nfunction createAsyncAction(requestType: T1, successType: T2, failureType: T3): <P1, P2, P3>() => {\n  request: AC<T1, P1>,\n  success: AC<T2, P2>,\n  failure: AC<T3, P3>,\n};\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchUserTypes = createAsyncAction(\n  'FETCH_USER_REQUEST',\n  'FETCH_USER_SUCCESS',\n  'FETCH_USER_FAILURE'\n)<void, User, Error>();\n\nconst requestResult = fetchUserTypes.request();\nexpect(requestResult).toEqual({ type: 'FETCH_USER_REQUEST' });\n\nconst successResult =\n  fetchUserTypes.success({ firstName: 'Piotr', lastName: 'Witek' });\nexpect(successResult).toEqual({\n  type: 'FETCH_USER_SUCCESS',\n  payload: { firstName: 'Piotr', lastName: 'Witek' },\n});\n\nconst failureResult = fetchUserTypes.failure(Error('Failure reason'));\nexpect(failureResult).toEqual({\n  type: 'FETCH_USER_FAILURE',\n  payload: Error('Failure reason'),\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action creator  \n> contains properly narrowed literal type\n\n```ts\nfunction getType(actionCreator: (...args) => T): T\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> (curried assert function) Check if action is an instance of given action creator(s)\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator: ActionCreator<T>, action: any): action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>, action: any): action is T\n// or curried function\nisActionOf(actionCreator: ActionCreator<T>): (action: any) => action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo } from './todos-actions';\n\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n\n// epics with multiple actions\nimport { addTodo, toggleTodo } from './todos-actions';\n\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n\n// conditionals where you need a type guard\nimport { addTodo } from './actions';\n\nif(isActionOf(addTodo, action)) {\n  operationThatNeedsPayload(action.payload) // action is asserted as: { type: \"ADD_TODO\", payload: string }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isOfType\n\n> (curried assert function) Check if action type equals given type constant\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisOfType(type: T, action: any): action is Action<T>\n// or curried function\nisOfType(type: T): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD } from './todos-types';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isOfType(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n\n// conditionals where you need a type guard\nimport { ADD } from './todos-types';\n\nif(isOfType(ADD, action)) {\n  return functionThatAcceptsTodo(action.payload) // action: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guide\n\n### v1.x.x to v2.x.x\n\n```ts\nconst deprecatedApi = createActionDeprecated('GET_TODO',\n  (token: string, id: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: token,\n  })\n);\n\nconst getTodoSimple = (token: string, id: string) => action('GET_TODO', id, token);\n\nconst getTodoVariadic = createAction('GET_TODO', action => {\n  return (id: string, token: string) => action(id, token);\n});\n\nconst getTodoStandard = createStandardAction('GET_TODO')<{ id: string; token: string; }>();\n\nconst getTodoStandardMap = createStandardAction('GET_TODO').map(\n  ({ id, token }: { id: string; token: string; }) => ({\n    payload: id,\n    meta: token,\n  })\n);\n```\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common action-creators variants (type only, with payload, with payload and meta)\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### - type only (no payload)\n\n```ts\n/**\n * redux-actions\n */\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination would not be possible) (🐼 is really sad!)\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types, only the data that is really there, also the action \"type\" property is containing precise literal type\n\n#### - with payload\n\n```ts\n/**\n * redux-actions\n */\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` param name is changed to some generic `t1`, literal type of `type` property is lost again and `payload` is nullable because of broken inference\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` still retain very precise resulting type\n\n#### - with payload and meta\n\n```ts\n/**\n * redux-actions\n */\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a complete loss of arguments arity with falling back to `any` type with all the remaining issues as before\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type (🐼 is impressed by completely type-safe results)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"8ee5785f30deabf45ca5418e079b890a751b8a26","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.0-rc.0","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-3l0Kiv6gWw+6KhDdS3SrEgcjXVyk2o+GKihVhFVJ/ryBaHSyn2x9T9SnTENUlGufhgcwmXGy12iSUexv3m9Jqg==","shasum":"271f958dff9e27641f456471e74fcb3ddf015f01","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.0-rc.0.tgz","fileCount":44,"unpackedSize":131709,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa9iRkCRA9TVsSAnZWagAAT0QP/3cGdaIjzVMV9bzORNOe\nB+cao+T0dtycvsJ0ymOC7SSxEf6k9gdR8h0uFrjFR/Gz4uxy/wu/HZXK52eM\nbALGC5qZsoawQR2m3mJ1tPEWecAiWi220YdFL2GjlaqXPNhwlHCASI6Kx4YI\nJivadPgEMSvcnwdTsugbr6cRdvia0zZGTDPDx7jOb55Gm3DRSYg/gcM1yOuX\n3Fk6vwuLFyuYVlgkivFpQA0ekIOUfxZB0U6QgXst0e9wp4f7BirZBpMGV1+v\naXhAfpRpf0IJ9ZYT3T46GmvkVJ+U8Un+xttoYAF/NSFpzpKDDikkX2Dblf7u\n9/n3wHYSmzbyKFfDzUwY2o/nckzTzLm+oyqedFrfNc0E6klAf3exnSqtG0J5\noiOmqzjeepbLT1vFadF/sDCyvK/jCGQLRKWAxs8++eV24ycA2n2A9dowKtk7\nCrPZNSCsuCvUfokPqDOpGJP+OnFZB1QvNyVC8nROibLBXGPNSA728BwRyH49\nCdRC17MGhAUUX/bCQ2/foS/Yi4pw4F5zYy9KGixpdIU84pLU2BxKNg9NVlFp\nNAgDYgnczKVOfSgVSxFZfE4ujcGQ0CiGyMszhERnRDGzqOEO4vvpcizUQm0T\n35yV8bPsFVH1/9VpTgvTAeqQIYMtW65SxsQSx0WbYxg38TXn6hRwufOS+gAH\nRLfs\r\n=x1dK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHKcT1vvF8g2hiaTFQLhcZdKgzrZIJeLjP4WrJtdBfWgAiEAqglm3XhGBKuyr77df/eE8WLiB02pi/lJD28NLAepHu8="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.0-rc.0_1526080611563_0.8511186220149618"},"_hasShrinkwrap":false},"2.0.0-rc.1":{"name":"typesafe-actions","version":"2.0.0-rc.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ && npm install","clean":"rm -rf dist/","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prelint":"prettier --write 'src/**/*'","lint":"tslint --project './tsconfig.json'","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json ./src --watch","prepush":"npm run lint & npm run test","prepublishOnly":"npm run reinstall && npm run lint && npm run tsc && npm run test && npm run build"},"dependencies":{"tslib":"1.9.0"},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","redux":"4.0.0","rollup":"0.58.2","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.5","tslint":"5.10.0","typescript":"2.8.3"},"prettier":{"printWidth":80,"trailingComma":"es5","singleQuote":true,"semi":true},"keywords":["typescript","typesafe","actions","action-creators","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\n> #### Reference implementation of Todo App with `typesafe-actions`: https://codesandbox.io/s/v8k8y3j837\n\nSimple functional API that's specifically designed to reduce types **verbosity** (especially maintainability concerns)\nand **complexity** (thanks to powerful helpers).\n\n### Goals\n\n* complete type-safety for payload operations in reducer with switch cases and conditional statements ([docs](#reducer-switch-cases))\n* simplify handling async flow of network requests with multistep composite actions ([docs](#handling-async-flow-of-network-requests))\n* simplify discrimination of union types for `redux-observable` epics but works as well for any other libraries thanks to wide set of helpers ([docs](#side-effects-with-redux-observable))\n* strictly check arguments of given payload when invoking action creators in view layer (TODO: [link])\n\n### Features\n\n* __small and focused__ - (Bundle size: 2.72 KB, Gzipped size: 879 B)\n* __secure__ - no external dependencies for browser (`tslib` in case of cjs/esm modules)\n* __tested__ - complete test-suite with tests for type soundness\n\n## Motivation\n\nWhen I was first trying to use [redux-actions](https://redux-actions.js.org/) with TypeScript I was intimidated by incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here to read more detailed comparison)](#redux-actions).\n\nMoreover alternative solutions in the wild have been either **too verbose because of excess type annotations** (primary maintainability concern) or **used classes** (hinders readability and enforce to use a **new** keyword 😱).\n\nThat's why I created `typesafe-actions` with the core idea to lean on incredible **type-inference** 💪. to reduce the maintainability costs of type signatures and also to make it feel like simple idiomatic JavaScript because of reduced explicit types annotations to minimum.\\*\\*\n\n**From v2.0 we added a complementary API leveraging generic type arguments to provide a very concise and expressive way to use a \"bag object\" as payload argument and cut the boilerplate to one-liner**\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Tutorial](#tutorial)\n* [API](#api)\n  * [`ActionsUnion`](#actionsunion) (RootAction type-helper)\n  * [`action`](#action)\n  * [`createAction`](#createaction)\n  * [`createStandardAction`](#createstandardaction)\n  * [`createAsyncAction`](#createasyncaction)\n  * [`getType`](#gettype)\n  * [`isActionOf`](#isactionof)\n  * [`isOfType`](#isoftype)\n* [Migration Guide](#migration-guide)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install --save typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the power of **type-safety** provided by this library, let me show you how to build a typical todo app in a type-safe Redux Architecture:\n\nHere is a link to completed todo-app in codesandbox: [TODO: link]\n\n### - the actions (a.k.a. `RootAction`)\n\n```ts\n// counter-actions.ts\nimport { createStandardAction, ActionsUnion } from 'typesafe-actions';\n\nexport const add = createStandardAction('todos/ADD')<Todo>();\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n\n// merge all actions object for convenience\nimport * as todos from './todos-actions';\nimport * as toasts from './toasts-actions';\n\nexport const actions = { todos, toasts };\n// then you can use: dispatch(actions.todos.add({...}))\n\nexport type RootAction = ActionsUnion<typeof actions>;\n```\n\n> **PRO-TIP:** merge with third-party action types to model a complete representation of all possible actions at runtime\n\n```ts\n// example of including `react-router` action types\nimport { RouterAction, LocationChangeAction } from 'react-router';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type AppAction = RootAction | ReactRouterAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - reducer switch cases\n\nUse `getType` function to reduce boilerplate and mitigate the trouble of importing \"type constants\" across the application layers (the principle is to use action creators instead).\nMoreover **it's a type-guard** so it will discriminate union type of `RootAction` to a specific action withing a code block.\n\n```ts\nimport { getType } from 'typesafe-actions';\n\nimport { RootAction } from '../types';\nimport { add } from './todos-actions';\n\nconst reducer = (state: Todo[] = [], action: RootAction) => {\n  switch (action.type) {\n    case getType(add): // TIP: if you prefer you could still use a regular \"type constants\" here\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - handling async flow of network requests\n\n```ts\n// WIP\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - side-effects with `redux-observable`\n\nUse `isActionOf` function to use action creator function to filter actions and to narrow (discriminate) union type of `RootAction` to a specific action(s) down the stream.\n\n```ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { add, toggle } from './todos-actions';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isActionOf(add))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n```\n\n> **PRO-TIP:** it works with multiple actions in array\n```ts\nconst logTodoAction: Epic<RootAction, RootState, Services> =\n  (action$, store, { logService }) => action$\n    .filter(isActionOf([add, toggle]))\n    .do((action) => { // action is narrowed as:\n      // { type: \"todos/ADD\", payload: Todo } | { type: \"todos/TOGGLE\", payload: string }\n      ...\n```\n\nAlternatively if you prefer to use type constants there is a `isOfType` function to use with constants instead of action creators \n\n```ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { RootState, RootAction, Services } from '../types';\nimport { ADD } from './todos-types';\n\n// with single action\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isTypeOf(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      ...\n```\n\n> **PRO-TIP:** you can use it for conditional statements\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API\n\n### ActionsUnion\n\n> powerful type helper that will infer union type from various nested objects or arrays with action creators\n\n```ts\nimport { ActionsUnion } from 'typesafe-actions';\n\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    }\n  }\n};\n\nexport type RootAction = ActionsUnion<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### action\n\n> simple action factory function, to create typed action\n\n```ts\nfunction action(type: T, payload?: P, meta?: M): { type: T, payload?: P, meta?: M }\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string } }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAction\n\n> create the action creator of a typesafe compatible action\n\n```ts\n// type only\nfunction createAction(type: T): () => { type: T };\n// createAction('INCREMENT');\n\n// with payload\nfunction createAction(type: T, executor): (...args) => { type: T, payload: P };\nconst executor = (resolve) => (...args) => resolve(payload: P)\n// createAction('ADD', resolve => {\n//   return (amount: number) => resolve(amount);\n// });\n\n// with payload and meta\nfunction createAction(type: T, executor): (...args) => { type: T, payload: P, meta: M };\nconst executor = (resolve) => (...args) => resolve(payload: P, meta: M)\n// createAction('GET_TODO', resolve => {\n//   return (id: string, token: string) => resolve(id, token);\n// });\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// type only\nconst increment = createAction('INCREMENT');\nexpect(increment())\n  .toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', resolve => {\n  return (amount: number) => resolve(amount);\n});\nexpect(add(10))\n  .toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst getTodo = createAction('GET_TODO', resolve => {\n  return (id: string, token: string) => resolve(id, token);\n});\nexpect(getTodo('fake_id', 'fake_token'))\n  .toEqual({ type: 'ADD', payload: 'fake_id', meta: 'fake_token' });\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createStandardAction\n\n> simple creator compatible with \"Flux Standard Action\" to reduce boilerplate and enforce convention\n\n```ts\nfunction createStandardAction(type: T): <P, M>() => { type: T, payload?: P, meta?: M };\nfunction createStandardAction(type: T): { map: (arg: object) => { type: T, payload?: P, meta?: M };\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// type only\nconst increment = createStandardAction('INCREMENT')<void>();\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createStandardAction('ADD')<number>();\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createStandardAction('NOTIFY').map(\n  ({ username, message }}: Notification) => ({\n    payload: `${username}: ${message || ''}`,\n    meta: { username, message }, \n  })\n);\nexpect(notify({ username: 'Piotr', message: 'Hello!' })).toEqual({\n  type: 'NOTIFY',\n  payload: 'Piotr: Hello!',\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAsyncAction\n\n> create a composite action creator containing three action handlers for async flow (e.g. network request - request/success/failure)\n\n```ts\nfunction createAsyncAction(requestType: T1, successType: T2, failureType: T3): <P1, P2, P3>() => {\n  request: AC<T1, P1>,\n  success: AC<T2, P2>,\n  failure: AC<T3, P3>,\n};\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchUserTypes = createAsyncAction(\n  'FETCH_USER_REQUEST',\n  'FETCH_USER_SUCCESS',\n  'FETCH_USER_FAILURE'\n)<void, User, Error>();\n\nconst requestResult = fetchUserTypes.request();\nexpect(requestResult).toEqual({\n  type: 'FETCH_USER_REQUEST',\n});\n\nconst successResult =\n  fetchUserTypes.success({ firstName: 'Piotr', lastName: 'Witek' });\nexpect(successResult).toEqual({\n  type: 'FETCH_USER_SUCCESS',\n  payload: { firstName: 'Piotr', lastName: 'Witek' },\n});\n\nconst failureResult = fetchUserTypes.failure(Error('Failure reason'));\nexpect(failureResult).toEqual({\n  type: 'FETCH_USER_FAILURE',\n  payload: Error('Failure reason'),\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action creator  \n> contains properly narrowed literal type\n\n```ts\nfunction getType(actionCreator: (...args) => T): T\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> (curried assert function) Check if action is an instance of given action creator(s)\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator: ActionCreator<T>, action: any): action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>, action: any): action is T\n// or curried function\nisActionOf(actionCreator: ActionCreator<T>): (action: any) => action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo } from './todos-actions';\n\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n\n// epics with multiple actions\nimport { addTodo, toggleTodo } from './todos-actions';\n\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n\n// conditionals where you need a type guard\nimport { addTodo } from './actions';\n\nif(isActionOf(addTodo, action)) {\n  operationThatNeedsPayload(action.payload) // action is asserted as: { type: \"ADD_TODO\", payload: string }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isOfType\n\n> (curried assert function) Check if action type equals given type constant\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisOfType(type: T, action: any): action is Action<T>\n// or curried function\nisOfType(type: T): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD } from './todos-types';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isOfType(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n\n// conditionals where you need a type guard\nimport { ADD } from './todos-types';\n\nif(isOfType(ADD, action)) {\n  return functionThatAcceptsTodo(action.payload) // action: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guide\n\n### v1.x.x to v2.x.x\n\n```ts\nconst deprecatedApi = createActionDeprecated('GET_TODO',\n  (token: string, id: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: token,\n  })\n);\n\nconst getTodoSimple = (token: string, id: string) => action('GET_TODO', id, token);\n\nconst getTodoVariadic = createAction('GET_TODO', resolve => {\n  return (id: string, token: string) => resolve(id, token);\n});\n\nconst getTodoStandard = createStandardAction('GET_TODO')<{ id: string; token: string; }>();\n\nconst getTodoStandardMap = createStandardAction('GET_TODO').map(\n  ({ id, token }: { id: string; token: string; }) => ({\n    payload: id,\n    meta: token,\n  })\n);\n```\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common action-creators variants (type only, with payload, with payload and meta)\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### - type only (no payload)\n\n```ts\n/**\n * redux-actions\n */\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination would not be possible) (🐼 is really sad!)\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types, only the data that is really there, also the action \"type\" property is containing precise literal type\n\n#### - with payload\n\n```ts\n/**\n * redux-actions\n */\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` param name is changed to some generic `t1`, literal type of `type` property is lost again and `payload` is nullable because of broken inference\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` still retain very precise resulting type\n\n#### - with payload and meta\n\n```ts\n/**\n * redux-actions\n */\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a complete loss of arguments arity with falling back to `any` type with all the remaining issues as before\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type (🐼 is impressed by completely type-safe results)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"12ae7f8a51ae9c3b0769c17afdf33a47d4bf55ce","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.0-rc.1","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-n8iCIsSpcKLeLT0dYZ1qA+pVzMHCxbnmV87Ym+NaYqXMe2RwsLKlXln+++/d4ARxcdpbYuVA6tBcf+EHXMrVIQ==","shasum":"04d1b8ab857093c20ee112c7bb43c8a78f415eff","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.0-rc.1.tgz","fileCount":42,"unpackedSize":131254,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+BdwCRA9TVsSAnZWagAABeYQAJkljLJgT7O2B2IIChao\nDkQvvGr2RdSnEzYv7uRqkQ+UBkOImiIG+Gl3ExHmIn67d47UPqKUFNjUbYiC\nLDn8oOf6qRXJ2DjaqHg8GKEpJZyjSn47ihaPXrVXlq1OMW7RLnKKTm1y1W5O\nPEPR9VxczyrX/CXDdn/gjNKMxNFFqJJt3FpM+rEt3kbm5lpYmcileFSE+edC\nvHp5qTKGVxbajyW+Lt7YkbG3FxtZJf+syn6HmNKlkI5MrJ8Gp92idpoiaxeH\ntHAECx/kyrbDj/barp/5deNkF986oQZqt/9ckJ0l65D6Tirde90nt5PT4bgr\nZSawrcMI8U5BvqthD4A2/CF9+2ciDrK/swQqzHYPRETKuXUNqSOx7aMkx4DF\nvXiiuYqDhZpEPKJtXGUMeW7ywr/HH5YsTIHh3bwFxRkGj35909v1RHw0hZxy\nCP+gd/23kUQ+JN6+lEppvVTCa9+vbnyD+WyUJpeHnojgfhLzkriK8VAmc71D\nlTo7Dk+cE0ckbObHiP3oDmcJJw4WEUrseH88KGSGcN4bYjp56kgXP5t5wEUR\nlCdo2aPYR1CHq6HtW5sAaOcTi81OUtFR/l899eGBpc+Mk/4hTFCeZIOnE7m7\nPIqItCKlB1XAhTwxsmz6v4KvXrATZClhgAS4otGA+aN3BXs9TZ6uXb9bEEJU\nkXe4\r\n=orAM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCO/sOYWLNbfFUsXwMtQdnm7WLZ/NYIB7WH08xlXSGAeAIhALqRhe0xZUTbiRGcqOi4JQAa9OcndpJ8LfR78zNKj9NA"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.0-rc.1_1526208367561_0.4753348173077043"},"_hasShrinkwrap":false},"2.0.1":{"name":"typesafe-actions","version":"2.0.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","check":"npm run lint & npm run tsc & npm run test","prelint":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json --watch ./src","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run check","prepublishOnly":"npm run reinstall && npm run check && npm run build"},"dependencies":{"tslib":"1.9.1"},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.10.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"6e470782e4d800da4ebade8ef35b2f33a81de759","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.1","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-ZUpAtGbMn/R3KZieScU7jkRzcEmq22trVKulLQeK0uZ4Ua3r4h7Czc+uMiCByO/x1CEv1f+rMe5uRugeYX1rEA==","shasum":"53f7430be38a6075646624c13b3435ac0460b641","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.1.tgz","fileCount":42,"unpackedSize":139453,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/TtNCRA9TVsSAnZWagAAM58P/imXYd95kzSLyyZ02bFI\nHHUf0fpZ7Tusgza4rplPPwL1l+RsMGTqpLrMNdcwtcoQq80NpBFxU22asS2U\n0zAfIa9w6nWcOqDucdgJQVwnvzlPf8Ze04297Uuf/5jZ62MyCBzN4L1G5LZt\nMTJhIqDaOsK5On7SHcflaqeN+BZTfb8PyxsvWVAJJqhM3NUR91XJB7zdaLAH\nc8F9cxKu7Iz/agpvo78XI5pBNW86H7kne14VwJjnd9WOnZZIjr2pj6041LbI\npweideiuF/OPyPtJmcIYImBgrmfcb4nc4npqevJVX38TOBFXdDPksaUVG7bF\nNcADcyUYmArMUvRYhpJ6alQSbLnr22HYUAdK4rLzyobNL3Iqo9+jIcjURCwS\nfJQaMEUbx9mSYJ70dqaH/ILKxTY5djHB6kMRvAMlO13ijGCVTlDQpMeHLcHR\n3M5t8LMizjdzqB2W4KP/aSAcBdbH8oDaVpHY/Z4dpXHcWyTCLzhnz1RmPHOU\nPDAzb0aSiyNiBz0LC5DDZvCFTpoHEk/wxWffs8ApsNuMOPp+suUf7KPWkEP1\nts1Kr62XkYGAvcL/GAkMJl18KQBSxWtGTWdpvJpth4FgjfzYc4mIg5qW+/Eo\nLmcqhPuqIQ4LTUVH1R+SuBA+XWMTcI8f3nw2xvf3U/L0y9/4DnhSokeD+7G3\np6uR\r\n=J0yn\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDPpSmjOOzMfB6+wNgOsXVm+fzboP0McL0s0/H1YiFTQAiAKVbh91zNgP4X7T5EgfT5ix9mZ/bk9aHFrDUblgHBiLg=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.1_1526545227862_0.5122849559372853"},"_hasShrinkwrap":false},"2.0.2":{"name":"typesafe-actions","version":"2.0.2","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","check":"npm run lint & npm run tsc & npm run test","prelint":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json --watch ./src","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run check","prepublishOnly":"npm run reinstall && npm run check && npm run build"},"dependencies":{"tslib":"1.9.1"},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.10.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"95813b75e6a6e99d1beb4ed95af727169293cae2","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.2","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-XcCrbtvOZQilznkQN79yS1EInx7m0iCOzUpNQeTWFOZ0RZ5fLiuJukfsqmF0NldAtBlsdrbmJtZmlXv83IHLJQ==","shasum":"6553f77537f372195e3359ed9f5d4db6602da975","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.2.tgz","fileCount":42,"unpackedSize":129862,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/V+ICRA9TVsSAnZWagAAL0UP/jM10sSTRJznKIOZ8Y+q\nRP4jqM2f56kkiPxz+u6KxwO309lLyreZQ2OvuCKyU1aX0rMQk1X8UEIi2Gt5\nzUEeh1s+FvZsIsHqrnK5qMzE81g0qw9fXH79D6saIJib7nsy3m/f0KF3voVb\nVUyx+ZFIXp0C4VuMtrzXWzdJok83OT8xPGtatVqRCqeQx0HYFHtiHW9CM4eA\ndKYet/hc4ODkoP71tCwxrWKfLcsnCo7/bwE1apTpYuMzlPgc6kETIeFAlZ80\nElKGIG1RHs0/ffO5o5bBpTSG+Uxkonbx6ysoSFRqD+84VUxSlsdyL9FJsMgb\nqTAUj9SGk8wZHCfKHMLj/AUBxp/TxAP8C9+wsvvjSL4C7uR7lu8t2bxNhWfd\nt0zbcNfK+FvvKcYKiWkpY4hUZ/bOEvr+FHIUxtrAz3fzEbD2hXVdr4ADxjBZ\npzjajhz5D7Jr5R2V5Ha1ZJeJJvgALhS1S7a1iusN6WTEtrQtQ05A/Gq7Bd2c\nbg1KMMv5OA+I//mc0YcW20EVPTp1ne1YsDF4XJLJ26NgZ24WUpUnniUQwvjA\nal98r7+U1u521JEUFNn6VILGv07EG4av0Q5F8lwjg4ojN2UYgOsfH8lEqyK1\n7OMJ9me6ANYk3JaMIRuSYicO7ZpkYSkHQYjQkjm5WTmvWs7vWIph01riSHxh\nPKpz\r\n=emC2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDTr7Hb511NVsKvxsuMjhOxGSsT8LS8+1ZEzWmHsGZPdgIgDNMXAmme16AXtepQdYkLh5QjtpQ8DFapwRNdF7awb8c="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.2_1526554503422_0.6050149849477975"},"_hasShrinkwrap":false},"2.0.3":{"name":"typesafe-actions","version":"2.0.3","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","check":"npm run lint & npm run tsc & npm run test","prelint":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json --watch ./src","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run check","prepublishOnly":"npm run reinstall && npm run check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.10.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"readme":"# typesafe-actions\n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n[ ![Codeship Status for piotrwitek/typesafe-actions](https://app.codeship.com/projects/d8776810-3b42-0136-36f6-4aa2219ea767/status?branch=master)](https://app.codeship.com/projects/290301)\n[![Dependency Status](https://img.shields.io/david/piotrwitek/typesafe-actions.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![peerDependency Status](https://img.shields.io/david/peer/piotrwitek/typesafe-actions.svg)](https://david-dm.org/piotrwitek/typesafe-actions#info=devDependencies)\n\n### Typesafe \"Action Creators\" for Redux / Flux Architectures (in TypeScript)\n\n> #### This lib is a part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)\n\n> #### Reference implementation of Todo-App with `typesafe-actions`: https://codesandbox.io/s/github/piotrwitek/typesafe-actions-todo-app\n\nFlexible functional API that's specifically designed to reduce types **verbosity** (especially maintainability concerns)\nand **complexity** (thanks to powerful helpers).\n\n### Features\n\n* __small and focused__ - according to `rollup-plugin-filesize` (Bundle size: 2.6 KB, Gzipped size: 808 B) check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n* __secure and optimized__ - no external dependencies with 3 different bundle types (`cjs`, `esm` and `umd` for browser)\n* __solid as a rock__ - complete test-suite for entire API surface with extra tests for static-types\n\n## Motivation\n\nWhen I was first starting with Redux and TypeScript I was trying to use [redux-actions](https://redux-actions.js.org/) to simplify maintainability of **action-creators**. I was struggling and results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(read more detailed comparison)](#redux-actions).\n\nMoreover alternative solutions in the wild have been either **too verbose because of excess type annotations** (primary maintainability concern) or **used classes** (hinders readability and enforce to use a **new** keyword 😱).\n\nThe solution for all the above pain points is finally here, the `typesafe-actions`.\nThe core idea was to design and API that would harness the power of incredible **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition I wanted to make it \"look and feel\" as close as possible to idiomatic JavaScript we all know and love ❤️, maybe sometimes we even hate but anyway...\n\n## Behold the Mighty \"Tutorial\"\n\nTo showcase flexibility and the power of **type-safety** provided by this library, lets build together the common parts of a typical todo-app following Redux architecture:\n\n> WARNING: Please make sure that you understand the following concepts of programming languages to be able to follow along with me: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and some [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n### - The Actions\n> Different projects have different needs and conventions vary across teams this is why `typesafe-actions` was designed and build with flexibility in mind and it provides 3 different factory functions, so you can choose what would be the best fit for your project. \n\n#### 1. classic JS style with constants FTW!\nUsing this simple function we'll have complete type-safety with minimal type declaration effort, but we're constrained to use constants (as in regular JS applications) because some of advanced **action-helpers** (`getType`, `isActionOf`) will not work with such action-creator. This is still very compelling option especially for refactoring existing projects.\n```ts\nimport { action } from 'typesafe-actions';\nimport { ADD, TOGGLE } from './constants';\n\nexport const toggle = (id: string) => action(TOGGLE, id);\n// (id: string) => { type: 'todos/TOGGLE'; payload: string; }\n\nexport const add = (title: string) => action(ADD, { title, id: cuid(), completed: false } as Todo);\n// (title: string) => { type: 'todos/ADD'; payload: Todo }\n```\n#### 2. opinionated without need for constants\nThis approach will give us access for all the **action-helpers** and eliminate to use constants in the application, but it's opinionated and will always accept 2 arguments (1st is payload, and 2nd is meta). It also have very usefull `map` chain method for an extra flexibility.\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// (payload: string) => { type: 'todos/TOGGLE'; payload: string; }\n\nexport const add = createStandardAction(ADD).map(\n  ({ title }: { title: string }) => ({\n    payload: { title, id: cuid(), completed: false } as Todo,\n  })\n);\n// ({ title: string }) => { type: 'todos/ADD'; payload: Todo }\n```\n#### 3. most flexible with all helpers\nThis approach will gives us the best of both worlds: all the **action-helpers** will work and we have the flexibility of providing variadic amount of named parameters like with regular functions.\n```ts\nimport { createAction } from 'typesafe-actions';\n\nexport const toggle = createAction('todos/TOGGLE', resolve => {\n  return (id: string) => resolve(id);\n});\n// (id: string) => { type: 'todos/TOGGLE'; payload: string; }\n\nexport const add = createAction('todos/ADD', resolve => {\n  return (title: string) => resolve({ title, id: cuid(), completed: false } as Todo);\n});\n// (title: string) => { type: 'todos/ADD'; payload: Todo }\n```\n\n> For more examples check the [API Docs](#table-of-contents), there are plenty!\n\n### - The Reducer\n\nHere we'll start by generating an **tagged union type** of actions (TodosAction). It's very easy to do using TS type-inference and `ActionType` utility-type provided by `typesafe-actions`.\n```ts\nimport { ActionType, getType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (use `TodosAction` for action type)\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\nWith static types in place we can finally leverage **tagged union types**. Using switch-cases on common `type` property of action we can distinguish and narrow union type of `TodosAction` to a single specific action type valid for the corresponding code block.\n```ts\n  switch (action.type) {\n    case getType(todos.add): \n      // below action type is narrowed to: { type: \"todos/ADD\", payload: Todo }\n      return [...state, action.payload];\n    ...\n```\nNotice we are using `getType` action-helper with respective action-creator as an argument to handle corresponding switch case. This will help to reduce boilerplate and completely remove the need of using **type-constants** in our application.\n> Note: If your team prefer to use regular \"type constants\", no problem. You can still use them with `typesafe-actions`.\n\n> **PRO-TIP:** I can recommend to create a `RootAction` in the cenral point of your redux store - it will model a complete representation of all possible action types in your application, you can even merge it with existing third-party declarations like it's shown below.\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\nimport { TodosAction } from '../features/todos';\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n### - The Async-Flow\n> Starring `redux-observable` epics\n\nTo handle async-flow of request to a remote resource in our application, we'll implement an `epic` that'll call a remote API using injected `todosApi` client returning a Promise.\nTo help us simplify the creation process of necessary action-creators we'll use `createAsyncAction` function providing us with a nice common interface `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for actions objects and action-creators, that otherwise we would have to write by hand.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodos = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<void, Todo[], Error>();\n\n// epics.ts\nimport { fetchTodos } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootState, Services> = (action$, store, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodos.request)),\n    switchMap(action =>\n      of(todosApi.getAll(...)).pipe(\n        map(fetchTodos.success),\n        catchError(pipe(fetchTodos.failure, of))\n      )\n    );\n```\n\n### - The Side-Effects\n> Starring `redux-observable` epics\n\nTo showcase handling of various side-effects in our application we'll implement an `epic` responsible of showing a notification when the user adds a new todo.\nIn the **async-flow** section above we have already seen the usage of `isActionOf` function. We used it to help us filter actions coming from the source stream using **action-creators** as an argument. It's also a **type-guard** so it'll narrow **tagged union type** of all actions (here we're using `RootAction`) to a specific action down the pipe in epics.\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add, toggle } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(...);\n    })\n    ...\n```\n\n> **PRO-TIP:** It also works with multiple actions as an array argument\n```ts\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\", payload: Todo } | { type: \"todos/TOGGLE\", payload: string }\n```\n\n**ALTERNATIVE:** But if your team prefer to use **type-constants** what then? I still got you covered! We have equivalent `isOfType` function that will work with **type-constants** instead of action-creators.\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isTypeOf(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\", payload: Todo }\n    ...\n```\n\n> **PRO-TIP:** Both helper above prove usefull in all conditional statements\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\", payload: Todo }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n> _PS: If you're wondering what the `Services` type is in the epics signature and how to declare it in your application to easily inject statically typed API clients to your epics also ensuring for easy mocking while testing resulting in clean architecture, please create an issue for it and perhaps I'll find some time in the future to write an article about it._\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [API Docs](#api-docs)\n  * utility-types\n    * [`ActionType`](#actiontype) (RootAction type-helper)\n    * [`StateType`](#statetype) (RootState type-helper)\n  * action-creators\n    * [`action`](#action)\n    * [`createAction`](#createaction)\n    * [`createStandardAction`](#createstandardaction)\n    * [`createAsyncAction`](#createasyncaction)\n  * action-helpers\n    * [`getType`](#gettype)\n    * [`isActionOf`](#isactionof)\n    * [`isOfType`](#isoftype)\n* [Migration Guide](#migration-guide)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs\n\n### ActionType\n\n> powerful type helper that will infer union type from \"action-creator map\" object or \"module import\"\n\n_NB: This is an equivalent of TypeScript `ReturnType` accepting typeof \"action-creators\" module \"import *\" or \"action-creator map\" type instead of function/expression type_\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n\n\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    }\n  }\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### StateType\n\n> powerful type helper that will infer state object type from \"reducer function\" or \"nested/combined reducers\"\n\n_NB: This is an equivalent of TypeScript `ReturnType` accepting typeof \"reducer function\" or \"nested/combined reducers\" (result of `combineReducers`) instead of function/expression type_\n\n```ts\nimport { StateType } from 'typesafe-actions';\n\n// \nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### action\n\n> simple action factory function, to create typed action\n\n```ts\nfunction action(type: T, payload?: P, meta?: M): { type: T, payload?: P, meta?: M }\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string } }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAction\n\n> create the action-creator of a typesafe compatible action\n\n```ts\n// type only\nfunction createAction(type: T): () => { type: T };\n// createAction('INCREMENT');\n\n// with payload\nfunction createAction(type: T, executor): (...args) => { type: T, payload: P };\nconst executor = (resolve) => (...args) => resolve(payload: P)\n// createAction('ADD', resolve => {\n//   return (amount: number) => resolve(amount);\n// });\n\n// with payload and meta\nfunction createAction(type: T, executor): (...args) => { type: T, payload: P, meta: M };\nconst executor = (resolve) => (...args) => resolve(payload: P, meta: M)\n// createAction('GET_TODO', resolve => {\n//   return (id: string, token: string) => resolve(id, token);\n// });\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// type only\nconst increment = createAction('INCREMENT');\nexpect(increment())\n  .toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createAction('ADD', resolve => {\n  return (amount: number) => resolve(amount);\n});\nexpect(add(10))\n  .toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst getTodo = createAction('GET_TODO', resolve => {\n  return (id: string, token: string) => resolve(id, token);\n});\nexpect(getTodo('fake_id', 'fake_token'))\n  .toEqual({ type: 'ADD', payload: 'fake_id', meta: 'fake_token' });\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createStandardAction\n\n> simple creator compatible with \"Flux Standard Action\" to reduce boilerplate and enforce convention\n\n```ts\nfunction createStandardAction(type: T): <P, M>() => { type: T, payload?: P, meta?: M };\nfunction createStandardAction(type: T): { map: (arg: object) => { type: T, payload?: P, meta?: M };\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// type only\nconst increment = createStandardAction('INCREMENT')<void>();\nexpect(increment()).toEqual({ type: 'INCREMENT' });\n\n// with payload\nconst add = createStandardAction('ADD')<number>();\nexpect(add(10)).toEqual({ type: 'ADD', payload: 10 });\n\n// with payload and meta\nconst notify = createStandardAction('NOTIFY').map(\n  ({ username, message }}: Notification) => ({\n    payload: `${username}: ${message || ''}`,\n    meta: { username, message }, \n  })\n);\nexpect(notify({ username: 'Piotr', message: 'Hello!' })).toEqual({\n  type: 'NOTIFY',\n  payload: 'Piotr: Hello!',\n  meta: { username: 'Piotr', message: 'Hello!' },\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### createAsyncAction\n\n> create a composite action-creator containing three action handlers for async flow (e.g. network request - request/success/failure)\n\n```ts\nfunction createAsyncAction(requestType: T1, successType: T2, failureType: T3): <P1, P2, P3>() => {\n  request: AC<T1, P1>,\n  success: AC<T2, P2>,\n  failure: AC<T3, P3>,\n};\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchUsers = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<void, User[], Error>();\n\nconst requestResult = fetchUsers.request();\nexpect(requestResult).toEqual({\n  type: 'FETCH_USERS_REQUEST',\n});\n\nconst successResult = fetchUsers.success([{ firstName: 'Piotr', lastName: 'Witek' }]);\nexpect(successResult).toEqual({\n  type: 'FETCH_USERS_SUCCESS',\n  payload: [{ firstName: 'Piotr', lastName: 'Witek' }],\n});\n\nconst failureResult = fetchUsers.failure(Error('Failure reason'));\nexpect(failureResult).toEqual({\n  type: 'FETCH_USERS_FAILURE',\n  payload: Error('Failure reason'),\n});\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### getType\n\n> get the \"type\" property of a given action-creator  \n> contains properly narrowed literal type\n\n```ts\nfunction getType(actionCreator: (...args) => T): T\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n\n```ts\nconst increment = createAction('INCREMENT');\nconst type: 'INCREMENT' = getType(increment);\nexpect(type).toBe('INCREMENT');\n\n// in reducer\nswitch (action.type) {\n  case getType(increment):\n    return state + 1;\n\n  default:\n    return state;\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isActionOf\n\n> (curried assert function) check if action is an instance of given action-creator(s)\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator: ActionCreator<T>, action: any): action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>, action: any): action is T\n// or curried function\nisActionOf(actionCreator: ActionCreator<T>): (action: any) => action is T\nisActionOf([actionCreator]: Array<ActionCreator<T>>): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo } from './todos-actions';\n\nconst addTodoToast: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf(addTodo))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string }\n      const toast = `Added new todo: ${action.payload}`;\n\n// epics with multiple actions\nimport { addTodo, toggleTodo } from './todos-actions';\n\nconst logTodoAction: Epic<RootAction, RootState> =\n  (action$, store) => action$\n    .filter(isActionOf([addTodo, toggleTodo]))\n    .concatMap((action) => { // action is asserted as: { type: \"ADD_TODO\", payload: string } | { type: \"TOGGLE_TODO\", payload: string }\n      const log = `Dispatched action: ${action.type}`;\n\n// conditionals where you need a type guard\nimport { addTodo } from './actions';\n\nif(isActionOf(addTodo, action)) {\n  operationThatNeedsPayload(action.payload) // action is asserted as: { type: \"ADD_TODO\", payload: string }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### isOfType\n\n> (curried assert function) check if action type is equal given type-constant\n> it will narrow actions union to a specific action\n\n```ts\n// can be used as a binary function\nisOfType(type: T, action: any): action is Action<T>\n// or curried function\nisOfType(type: T): (action: any) => action is T\n```\n\nExamples:\n\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD } from './todos-types';\n\nconst addTodoToast: Epic<RootAction, RootState, Services> =\n  (action$, store, { toastService }) => action$\n    .filter(isOfType(ADD))\n    .do((action) => {\n      // action is narrowed as: { type: \"todos/ADD\", payload: Todo }\n      toastService.success(`Added new todo: ${action.payload}`);\n    })\n    .ignoreElements();\n\n// conditionals where you need a type guard\nimport { ADD } from './todos-types';\n\nif(isOfType(ADD, action)) {\n  return functionThatAcceptsTodo(action.payload) // action: { type: \"todos/ADD\", payload: Todo }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guide\n\n> NOTE: `typesafe-actions@1.x.x` are best used with `utility-types@1.x.x` which contains `$call` utility that was removed in `v2.x.x`\n\n### v1.x.x to v2.x.x\n\n```ts\nconst deprecatedApi = createActionDeprecated('GET_TODO',\n  (token: string, id: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: token,\n  })\n);\n\nconst getTodoSimple = (token: string, id: string) => action('GET_TODO', id, token);\n\nconst getTodoVariadic = createAction('GET_TODO', resolve => {\n  return (id: string, token: string) => resolve(id, token);\n});\n\nconst getTodoStandard = createStandardAction('GET_TODO')<{ id: string; token: string; }>();\n\nconst getTodoStandardMap = createStandardAction('GET_TODO').map(\n  ({ id, token }: { id: string; token: string; }) => ({\n    payload: id,\n    meta: token,\n  })\n);\n```\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common action-creator variants (type only, with payload, with payload and meta)\n\n> tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### - type only (no payload)\n\n```ts\n/**\n * redux-actions\n */\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible) (🐼 is really sad!)\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types, only the data that is really there, also the action \"type\" property is containing precise literal type\n\n#### - with payload\n\n```ts\n/**\n * redux-actions\n */\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` param name is changed to some generic `t1`, literal type of `type` property is lost again and `payload` is nullable because of broken inference\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` still retain very precise resulting type\n\n#### - with payload and meta\n\n```ts\n/**\n * redux-actions\n */\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a complete loss of arguments arity with falling back to `any` type with all the remaining issues as before\n\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type (🐼 is impressed by completely type-safe results)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <mailto:piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","gitHead":"776d17d20d6886771c17d6843259b143b572d2d7","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.3","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-r9DKt6vMjBIqJvjzOM+bokRGxO8HNLFJ62vUea6afji9W82nDIvW4d/BNh93I0TYhkOyMc8o72vhw11nILY3oQ==","shasum":"5451a4f8bf0d1e79f7d12af7582cc5f12d490708","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.3.tgz","fileCount":42,"unpackedSize":129838,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/WKSCRA9TVsSAnZWagAAXncQAJuXvydi8l6JLUu00pMe\nGuVC4OxgXOd1wi0hTq0lUBOF0W9HG4vC3vOokcHqboBvA5l30baaohL1BMOa\nV6xff4ts1QAO/ErcE9VaoIYBQLZOnMD+c3tsSckbDnWVEWHNLCwWeu8JkQ1u\n05CB4xUKQnzuCgIiNLbxphTTsxxYl7PQWltk+53ZPphryIr5z6IuN8jSOyjQ\nM1CK98xdpDI3LcL8ODADES4z/cuZFLex3sykUKpphH6Xw83iV71IsazxPQjr\n4e2EZ8qfR4L7f7Plx1EZ+GxghL5IKJUmya7RLFLAhXbWxLwrmKw+5IdSDbgc\nu8uW+0ncrFIvXekcBy4npyhh9IpK5y2ccudfXT2lmdcH6wNro5LFFPuSJdKk\ne/LlHQWp/o4rwsw/vlxNC30Q7zJjFtDsH76i/LvvxPRLB2vgGpczHXiJhTDC\nX6CzJmmnvhSp/sB8uNvvGlq1WWCaaIvsunrJXZqDnPeiBK8OUBV0GewikTuR\nSu+2cNkJcAlphmkm4iZNZL7w0tlHHyZgYBlmSFJM2UKdzNSfEXCZO45cnQ9I\nGHglmpQ/HcaBO1hyWqBhGqLfUQD23PMrUx69gxBUZ0HCZ1DMp23ACzJABZto\ngM4GnIsI7Z2Y8qHg+vTillcMMEvDQMTWdaDV2PtQPfXBQ8HTpBS4UEJoFDJz\nSODC\r\n=Qos9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCcqV2Aygs/7M88PVLKj1KRrMNLD0ca1EVS7EBasV+TcQIgWFmdBNJ7eCHYwKs70Ifk0HjP4Bb1zc9LDs3LIJJbIfs="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.3_1526555280507_0.6571373100067486"},"_hasShrinkwrap":false},"2.0.4":{"name":"typesafe-actions","version":"2.0.4","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","check":"npm run lint & npm run tsc & npm run test","prelint":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","pretest":"tsc -p ./tsconfig.spec.json --noEmit","test":"jest --config jest.config.json ./src","test:watch":"jest --config jest.config.json --watch ./src","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run check","prepublishOnly":"npm run reinstall && npm run check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"22.2.3","husky":"0.14.3","jest":"22.4.3","prettier":"1.12.1","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.10.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"203cd3f5ae33410366d74bf2c6ac78b1ec0e1a77","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.0.4","_npmVersion":"6.0.1","_nodeVersion":"9.9.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-3qnSDBNtH3mfekmM9w/IVlsqiUT4I5m+mpLp5tV2Ua/28BfaehqUg6eQNC8+cTk+oufbXcubLiWvKS/61qgleQ==","shasum":"31c8f8df3566d549eb52edb64a75997e970c17d0","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.0.4.tgz","fileCount":40,"unpackedSize":127042,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCqIUCRA9TVsSAnZWagAAUOQP/204vJv/1wH6Ff5KFtN/\nAMqwck5lG5owGQvetg2iwbPED/s761skh9/z82bhGTW6lZ+eRsusxrRJiTUM\nD/miMbRcnn7/v40aZua3EHcSBr44mRUmz0kayDFt2PyvXhjw2LVBZHPUov3d\nvCJHKiwMjCm74za9DrajmFq4eHuyCXjpb9jrLmsARFrdkGB5KRpDMkV4VAlV\nSKwwcD/3RX2EGjlQZd09xnD6pwgCPJf5DBEs6qBTcqWUO82wPKXTRQkc0mQZ\nkkrgnnNQUdLUq1kVP8Cy/4W3eefDWvH+oOx+VUQsnORLMP38bUNNewT1IpnC\nYaX8qpjA8wSWeAUnWtvzCneeHRvsNJ1AjBlLvt5L6vreiy7LGdFp2xEEBrLZ\n5E2VTRR2jVK9QlrdxzvjBm/l+IN5IyRtfX3K6dqHmLSjkCbFttMmJhLA7fnI\nFOJcZYmhA6Z2fasPOhQnHAMbvQvzCb4Cg6wv+T1+fT2T9lU/gD+sonAuSXEn\nay+98qXVNhBJpA0i7jHjXYyq+JOMG4QlTDPEf7cAu1Tf9Z8WIxCzG3tZ02mO\nMzi5u6L6ADGgob9VwlsC355UL6ZDDiiTHlsFJQYQn4PuT3Q0xv7jQTc3dW9V\ngzHLLA/ki/D3sMjiuc3WRPN32ygGoDZ0ngIKZaR/xiosST1YGbGzgwS/x98B\n0YuF\r\n=1r4x\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD1NUsusSNRqXIfCQKMVAjc2bL/U9FVG2zzcTzks+X1lAIgESg/GQqgHmtEf13YERdtCXN0AiFf0z+hrAYNg2Hrg2c="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.0.4_1527423507482_0.5894539305211717"},"_hasShrinkwrap":false},"2.1.0":{"name":"typesafe-actions","version":"2.1.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","precheck":"npm run prettier","ci-check":"npm run lint & npm run tsc & npm run test","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run ci-check","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"23.3.5","husky":"1.2.1","jest":"23.6.0","prettier":"1.15.3","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"23.10.4","tslint":"5.12.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"4bc122f866303bee86eb8535c10bd379ec36a283","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.1.0","_npmVersion":"6.4.1","_nodeVersion":"10.7.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-yyPfUO8YizWsUS/r9WujlJ1PwsmYu8DFnYx9mAqWNWUCtsH1lbOWbtWo++LERxm7IZJ0pT2R4PMPg03SFWlDlQ==","shasum":"37bd4c1b421fe68c0ace286d3e64b382e1264605","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.1.0.tgz","fileCount":40,"unpackedSize":137582,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcI6H0CRA9TVsSAnZWagAAd8gQAIs1RvQFnTEw/KicwVQH\nqioP8jak4dXwM545THqEWFYyLT99CT/YrutJDfB5Cqz83JB9RlVr6s7tVrU6\n4UInLdOdUAY3/4B4g/gltxVHV2PLHVMtfsK9zYFidZGFyB92iyxpu08tmKA+\nBfABy+u+SIkq0wKDcJmnSDSkpMcJYZeMexbR9dln+VPmN6PhkuRDd207zty3\nw6McyXFBWiB3Z603gvYn0ME3GCRzda40KhJ947EP3pVI/AyIe81zotwHvToy\ncHbzBP9Y7kSX+onPrMtH43epp0NQmsnxSvhbuNvrZCAZ0PV1kFFUR1ucJUXY\n57PnDYAeUslAa6ye6myB/iWkz9m9TvJ3t3yXegSTml3kmfSVRA905yhq2D/w\n4Nfpe9u4aXPLK+Yj1buM6JCQP5yoFCc5yrpLlaUWqnTd1kDStWSRLS2QuKZm\nK3FZphpv2KN4Jz0BrLNaRHwlUJCHZ8KX6JkR1CLsKRCeD0QsU3wQmceAiBxc\nVzGOM0xsaxWaCSUiAsuZI+wN8V8S89bTi/eC/0em0PZEUii9h3ZJskiVzQn+\nykjMq2qXyXoOYVUNa/tGvqOFlSAHkr2ikYTdqyT+jVyoHM8NbkbttBe9NW6/\nvfmzODI0FP2OYqpZEl3htCGnPzu1/hvTxJppRbz5AXUddD0h9DZvcYHijbcJ\ngyHA\r\n=QRYI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBkYarGvTmVd2LAMlkLOfdiOdDmZkH0pS2rG7rslfmLDAiEA7dmS2S5kHL3HELsMW4jmlHwoD5jy7NLteQYVi9NEjGo="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.1.0_1545839092031_0.4388491623233626"},"_hasShrinkwrap":false},"2.1.1":{"name":"typesafe-actions","version":"2.1.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","precheck":"npm run prettier","ci-check":"npm run lint & npm run tsc & npm run test","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepush":"npm run ci-check","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"23.3.5","husky":"1.2.1","jest":"23.6.0","prettier":"1.15.3","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"23.10.4","tslint":"5.12.0","typescript":"2.8.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"aaa91ca557550806f855efb852d4d9d9e703d27b","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.1.1","_npmVersion":"6.4.1","_nodeVersion":"10.7.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-QSNsMNDy90fcjYtNuP8tSmlarQP/+rzryPZFEEMQJpBDSiTaFZ4CYRwUGc8AuiSbuED5tnDZnfyA7DUXk4K8SA==","shasum":"7fda76b8f448e44cfbadd477b88fcc5cf08ff6fd","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.1.1.tgz","fileCount":30,"unpackedSize":94302,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcI6QsCRA9TVsSAnZWagAAQuAQAJxulBwHE4JrAnn7jBDt\n/gsOJjzg01T9TBa0wcXCTgxQlntkkCFkfILLyRRgfGotLXNV3ZlEB1+/mQMG\njAjF0BtIAR7Q97ty5tzQIOnwA4kozqqt5O70u6Q7NumG6psDZHOIZwFiPI0G\nL3glpvFGLoG4zOv46FnYCnFWggFj2ocBeyScALnPhCQBJiDheDCpraEwK2IS\nkF8HKyskILWnKXxiVClwDB7caWcu00SA2B//owBNL5fts1/JyXmJGad1ekkr\nl6EnhDSxvt+yVPiVElW136BU8vtFVDcCVEIasH62PT78j0BvkfrVEAHpJeL3\nsL6j0TMxBDGb1XybX/TgoF1R6NFjoaLhTluUUSmdmJJ68jSis5ZGTTqKJP8M\nONJZzjCmFUQE86jEKUKrYUTLjUBOi1cFIGF7dA2eENlDWCc74mWMnHx69lsX\nI5MgigrsZ9lIoHPGYdkmPR94WE2qCOh+rUHHZaCg9/lXr98RJpJs8idb35rP\nUIzKXF5Lmdh/C0IYqRClXXwpefJqRa+uE3GLxqLEIE7NEfoe/YPWZUUXYwL0\n/+9N4/Tb+Ar2TDNjFrAOaQYZMJGMuC5nT+mLrFIagwFCD6IobVmslgtX/vXa\nlX2eckzO8LtnkHWiBNqEIKJHY48DRbvRU+JQAzMV1A2GIE/r0AOSd2BdtKnF\nwXxh\r\n=+Q4B\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFOqZpsWAtbQPSHckvgSfWMe8y0lC7ZNcOnfuboJHMSDAiEAmZQ3/MCLkSgZAe3yRQpjK5QLyp4lDIh2k4P0QCJBFj4="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.1.1_1545839659335_0.621978030607615"},"_hasShrinkwrap":false},"2.2.0":{"name":"typesafe-actions","version":"2.2.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json --no-cache","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && (npm run tsc & npm run test)"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.15.3","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.12.0","typescript":"2.9.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"9ab6de7032624c32e03ad75bb0f8f40993b73ec1","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@2.2.0","_npmVersion":"6.5.0","_nodeVersion":"10.7.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-qjrFDl6S2yejKEz0M2c3c5D5z8sGJTjma94O9kRHStiqauXP9dKUM0Nbdmn90HCZBZl3jzFNT21bOtxRfCkc0w==","shasum":"2d2d8e403745446852f9f88ebf45ec07fa58c0fe","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-2.2.0.tgz","fileCount":32,"unpackedSize":101896,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcKNGtCRA9TVsSAnZWagAAvBIQAJe3vWn5k4D/MWG5VJ1m\nOGI6S20UnpsZ6t4tCz1PlHRG60wf/DE+adt3vvmdQLwqwJYGyzRck8qNfPjw\nAaYUJuwvkoy1u5I/5c0XT9tbja0lOhTfMHGgg1Y9xur9Kj9OMfpKmFlXfDzx\n6GSPH1O+9wPnrAsRQX+AMyMFktztnYO0XnKqRW1ziIC6V2IHEEFfk9OPiF6P\ntLbJa6tc53jtS5jDsB575iRmwaFOJJ1TywIiqnKuQhVeaTkmDYOullnF2vYR\n3nXO/oIodQ7uRCYeRmejjgBW6VZdrR/hCqXyEZyPRCklKHDb9hepi0kJJC1n\n1lEmiSvvUSJm0Yesz4mjicj7hvNCkaP2kNe5u4mHlhVpkCCcUI8IHiQ5fhUG\n0q6m2l6Avi7NBFSsRatpuAnAN5uClhNFmJiWhseM16cA6zIsb4ilCSBe8+0M\nbos5Ymc5U2brK7vru7hF2AQHetBVFce0UWnQWf+qw4f3ba6MAPKIku5ltlCR\nN15ilga0nInUPj1yUlNCljoIq27jHdz2mi4FhjkwG3ls5yfGPlkiFQ7ifZrd\nsutDeuOx74aqIK61zWrWL+coSM3Mdj6/Nptx3R1xZvGbmAB+puzCK3Ry90Zo\nBcweJ5sPwgPky9BrWjqzq9NnhFqDlxYXMzfninLHQ+tKfe+oI79U7T73ckl4\nXvQw\r\n=DpUA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCLsf+9cMipYwXHVEH6YUsVyezZJVs5RMTZVMI5/daKIQIhAOIPemjwJI+R1aFG7fzY17fvTtTkivXwiYJSjXcI7v54"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_2.2.0_1546178988391_0.10948301259979565"},"_hasShrinkwrap":false},"3.0.0":{"name":"typesafe-actions","version":"3.0.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json --no-cache","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && (npm run tsc & npm run test)"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.15.3","rollup":"0.59.1","rollup-plugin-commonjs":"9.1.3","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.12.0","typescript":"3.2.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"79600465a80fad57d3e77b8c54fee2d3679e3f9c","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.0.0","_npmVersion":"6.5.0","_nodeVersion":"10.7.0","_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"dist":{"integrity":"sha512-NLpRc/FY+jPfWL0aUXQzjxPyF0Xug2om6akaoRLQ18KGwP2yYNBJu9vkv2q1q+Cx/+edy2Qf6O8xXnYY/xwz1A==","shasum":"8b162ea11fa7383d4b4d96afc181118e84e06e10","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.0.0.tgz","fileCount":32,"unpackedSize":102036,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcKNM/CRA9TVsSAnZWagAAmagP/1HhAXQtO0l0En0kPMTy\nMVs1IhcNL6Cub6JDUhjFahx1O7/hMrlZz2mSMYrqcO9L+d4M2mS5r4nsLsuu\nfmlF+eiaH3EsJUZT1XdrKPU6MSGUyDtPREJ/m+/hiaqoPlp7WltwMzNOFeAl\npKD9DrIWMwEvEVNaxApkctPJFpMz/XGfySuicJ0P19WMDF3i28TH1YDIECR9\nHi+CMekZL1rMx9oP1n7HBuF5yAyMbojrVkkYbUtEWbgPr4ijtU8PViKWeEhg\nRmQKAXA5j3zcByXQJYicthonszftTRYr+TlN2aVd0ejpfJu/n2kmd75R9lL3\nsZ3g2ujqbcH3v0Wo2melVQSh7OqxjB/2Vb11ma6llSuC5ESoEWuuvEPYfs6k\nxcCmQVe+8yHQXrafw/vA+kLE7ZG8WmwCoO2PxcAJYW2ek2sz8dcdcKWddjvE\n1Ay9/zj1oiIHXm7TpPCUOvVyAwCccQe1kQf5OeX8uwJH68F6imKc78gmR5pX\nvd5u51aDuTBRVnvNDdM9S5p/aADARwIj0Nk6cca8m/H6yq4d38MXrgy4nzCU\nS/A5LeaRO/ssSZE8SibxX+K289oX1jAmGf/vyqwh8RzFURWiI+tFv6k/ubJ6\nfl3avbG4rBQcDG14an+xoJ/ei4ofHdpxsLuyOXF0AFE264w7MpyZdpSLFAAK\nn4e2\r\n=k9v7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGndMZ628O2vhT2dzUoYVNBMbfw+zU7ho8/LG2U3MDGrAiANWS1HVJYmvFwKoShZLarYA0SB9fY3yb4aFSTkfCBK8Q=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.0.0_1546179390418_0.69712800315972"},"_hasShrinkwrap":false},"3.1.0":{"name":"typesafe-actions","version":"3.1.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && (npm run tsc & npm run test & npm run test-types:update)"},"dependencies":{"typescript":"3.3.3"},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.0","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.12.1"},"optionalDependencies":{"typescript":"3.3.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"ca41679fc8f49d885919d0c64de70ef86fbce1a1","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.1.0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-ChLrqMj6DVf8cVKxeIjp6EyA9AyJWJfg00MTuQjDf3MVW4si09P3BQW8JuWQA9Ag3vcRVHzUCPCvaXLa4RKsSQ==","shasum":"02210286145939b3b1ead2d71829a8b588592706","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.1.0.tgz","fileCount":39,"unpackedSize":141468,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcZzKaCRA9TVsSAnZWagAACkgP/3YhFL3eQnejGAZMiTAK\nvY4Zxd7ELE9rP0xmwFlCVMuNIYB9Dhbd/NgwnGsz5/IhFmOfzRT1/L7Jzfmt\n/dtNYs63HcoDmMl42v1qBR/ATjdrtLkItx1LidjwsviNCXyvAeEHuCpHryhO\n/SpZG5DEQBliCJ7s4gGCZoZg6KG90BUeGUcADIKA1c9wlzv3Qhkpr56O6n/T\nHaNFzgM3ALL6JKb64QoF30iEsYLur+/+I9405gUS3Gyl8+10trETZ6wZgcBd\nSO2wCRCfIYFritxy6lSBnID2uIgsAeV8QvCVT5LTh451Hznva/EX5O4PLi4w\nteUyEVEdlPIPfJ5WHAQY0+3VOTLvG2dD88LsdTbfLGMT3VnCU8NfjymBOGeh\n6s3H/UmrsyuTck9bH8UHOkC8ybtIEnHZ8CwCBRbshgVf60b9C2mUtHRrb+IL\nzmljsUR4wr3y1dqvuD+JggYcpS9dDNHQQZuEDHIzH0fcjSFy4ZNYXUdi/Lsn\nnOFv706u9n5b/7FIvpY3IUMu9TdyAK0XoSes0jX00mO4bjdWo/4/Bg5I5U03\nKSpG+w8L8szIrakkiMAUz//gIcTWUGY00JcMse9CwHBKEl4Wz+yUJ/miF4Bg\nGgaePBgOr+4r5yD1bCmhvOFk/9bKoCVs2bLdoolUslSHyWyf7P2Xgc+L/lBe\n1iHY\r\n=MYtA\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICZUPaxuLcMUVMnRsAQ97YE4IVPEO0d+NllFxEctsz2xAiEAmTB9PsEejgIx+BU2m3NkqXiKYzczFJvjGQPkEdPdhEA="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.1.0_1550267033280_0.6234862860257191"},"_hasShrinkwrap":false},"3.2.0":{"name":"typesafe-actions","version":"3.2.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.0","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.12.1","typescript":"3.3.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"1f828f9140016170576c420fada7c1caf744bc0f","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.2.0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-iEYVa6I8yXFPxN8hi8/aQ8BustYBa28YGeF5b0F35w2LMzCXY/7POJtppki2pxszqhSVwoT0sq2q4FbeTrXalQ==","shasum":"b2b27f3fa6937b97de1c56b7412ebd5d1092d683","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.2.0.tgz","fileCount":40,"unpackedSize":146675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJccy5qCRA9TVsSAnZWagAAjjAP/A8ORFBH7XhZbaPGShFN\nLXRxALKik7zyfRGFeNUr4EP1RnKwkW3fC2WuoWnK/eJE3O/L4veZ2irANymS\n9/6T4kS1OjVv25LER0AfQaZlLdHuIjlDS7bcZLjq2PLb3yENgp1AEC2kS+/h\nSGqgkBzZI9iHIkEOV73QxLhL2RcfikosyQTP6fWY2SKsmbAADFGfgqrdshRM\nf6G1k0iaR7yiUOHBzmCT0IVfldJoQBzvA4iKh1smuzcvHqGFsXWCGA+qR9QS\nHDCUzXYGLy+/j9VdEUief5rE4vKwWAGfRbzcDKry4bVnyrT4Emmk6AmI8nKL\nXeCLGqPhOLhCUz/cvDODt6a+zjlg/GAkByIepL26mdo5Xtw48aLBfhb3bMec\nLaX9jzfhZigT8JsjkOzEUfhI88dPQiO+767C15aOjr8CHThmY6yZj3lz3ybN\nwS5bk/5IoNk+TjI9aPiiRY6jcZ9jqhXvhG9bOA8M5rLyeV3J8swH1fHTp625\nLx88tKjr7IyHxys1tW8a46WbdNQIxrp0MbBUwtPAZqb1uwid3p5+7xgokQ/i\npkp8fBPybyua5jvlvTu4OlcbS8EEzgyVODzrplTw5bqq5/0sQ+c8Y/7j7Qee\ncDxTh/WjoU5/CrzTgdHQKC9dbcBmf8K38QPSIWKrITgiEZpxlPOYTk3sCtUu\ncHt1\r\n=4q/R\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEKG1KgIx19HLp9rYMMZ6zX65RzkpR1uIS2B6nQZIArhAiBEFusJsQKEHSwvuXI+WiHEMZPpCCZgwpwsFRzzVQcLVQ=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.2.0_1551052393536_0.9784895783358918"},"_hasShrinkwrap":false},"3.2.1":{"name":"typesafe-actions","version":"3.2.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.0","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.12.1","typescript":"3.3.3"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"f69d46b9794e0d7b5822d041ca4671eed0397b15","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.2.1","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-hvhuNqsai6LzXQ+Hl6vajC9bGd/kHHL1hJvI4GQ0Rs6Fax1cjbNEsuFGy/RbfLPhBAL10n6DECEHUa+Q9E+MxQ==","shasum":"833623a4079eda5dbcb775113f6dcf02b71c03f8","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.2.1.tgz","fileCount":40,"unpackedSize":153830,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcc7M3CRA9TVsSAnZWagAADU0P/A7O/7wNSVAvRLeZiNxQ\nCMAA6k4FWEkiz8W/Rq7Ssbm07V+DxG0v7TjmHQF9EEuDtLEwUGhFzey/77Od\ncD/qvJE4tMef7Y8r7AILqPy6NUlv/wcBUpmYij0Cp/HXoGXS/cQa6/dRNdwe\nm3sYiW923SCQzRVzAeALy/yAzbfpFHOZzJs7CQobmW+mtS2SIYBqYgq6EETv\n++kPzgJ7gleTZ4RSVGBst/VhB41JER6UILQXRmuX0MXyOMQpdGYqxbky1uZ6\nfP0lwpMe0F9JT1co0kbcUlGLsyKWwgc2tjtSXCatmU9DAahFztqyYZKwkjK5\nKGh1HhUja2EB3xnkVUdYbOYBnjj0bfmwhBXjxygo9HJD2rUCJvtzgzZuaznv\n1Q6TwNIu91NcIqUi6HL9AD5hfOXkrHZGd0+TRKyVNYVtvTAo61bE7fJWshpm\nLxdMDqpnL/PiZiaiXAWaLeEoDlC+MNVWA/i5IvSRPjcr6NX7mgU4GpTXlOl1\no25lrz3eiCn+YohSUxSbkXMKAckQ/mWbuty7TMOmCBZGm+jq31SO+JCxMo87\nlKKdfcED/8wpiHVYl1eyuW9ESkf5uVq6ExOSYkqtfMbyPaTLgp0uy/CEde6Z\npbUYOegmd6NSXZJOhvuTG6OzZQfoYevN/cNKXl8i+Vi6iKxLvQgmwB5EySnB\n/Wsc\r\n=L8m9\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDKSB3hfUfVxzO7oaKkrsFrhv7N2ZZYPkYE4eSbMClC1gIhAOl1d15XTIXaP9ntIeJfgGv4QsiDX+Hd17QiHvupEOBw"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.2.1_1551086390141_0.7554939435470429"},"_hasShrinkwrap":false},"3.3.0-rc":{"name":"typesafe-actions","version":"3.3.0-rc","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.2","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.14.0","typescript":"3.4.1"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"d4d1719d69fd5a69fca0e7e673803c871f6cd6a8","readme":"# typesafe-actions\n\nTypesafe utilities for \"action-creators\" in Redux / Flux Architecture.\n\nFeaturing flexible functional API that's specifically designed to reduce types **verbosity**\nand **complexity** (explained in [motivation](#motivation)).\n\n_This lib is part of [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)_ :book:  \n\n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Build Status](https://semaphoreci.com/api/v1/piotrekwitek/typesafe-actions/branches/master/shields_badge.svg)](https://semaphoreci.com/piotrekwitek/typesafe-actions)\n[![dependencies Status](https://david-dm.org/piotrwitek/typesafe-actions/status.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![peerDependencies Status](https://david-dm.org/piotrwitek/typesafe-actions/peer-status.svg)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n[![License](https://img.shields.io/npm/l/typesafe-actions.svg?style=flat)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Bundlephobia Size](https://img.shields.io/bundlephobia/minzip/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n##### :star: _Found it useful? Want more updates?_ [**Show your support by giving a :star:**](https://github.com/piotrwitek/typesafe-actions/stargazers)  \n\n_Now updated to be compatible with **TypeScript v3.2.2**_ :tada:  \n\n_Reference Todo-App implementation with `typesafe-actions` on [CodeSandbox](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)_ :computer:  \n\n### Features\n\n* __minimalistic__ - according to `rollup-plugin-filesize` (Bundle size: 2.6 KB, Gzipped size: 808 B) check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n* __secure and optimized__ - no external dependencies, bundled in 3 different formats (`cjs`, `esm` and `umd` for browser)\n* __focus on quality__ - complete test-suite for an entire API surface containing regular runtime tests and extra type-tests to guarantee **type soundness**\n\n## Bug Report CodeSandbox\nYou can use this CodeSandbox to reproduce bug reports: https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox\n\n## Contributing Guide\nWe are open for contributions. If you're planning to contribute please make sure to read the contributing guide: [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n## Sponsor\n**Typesafe-Actions** is an independent open-source project created by people investing their free time for the benefit of our community.\n\nIf you are using **Typesafe-Actions** please consider donating as this will guarantee the project will be updated and maintained in the long run.\n\nIssues can be funded by anyone and the money will be transparently distributed to the contributors handling a particular issue.\n\n[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/110746954)\n\n---\n\n## Table of Contents\n\n* [Installation](#installation)\n* [Compatibility Notes](#compatibility-notes)\n* [Motivation](#motivation)\n* [Behold the Mighty \"Tutorial\"](#behold-the-mighty-tutorial)\n* [API Docs](#api-docs)\n  * Type-helpers\n    * [`ActionType`](#actiontype)\n    * [`StateType`](#statetype)\n  * Action-creators\n    * [`action`](#action)/[`createAction`](#createaction)\n    * [`createStandardAction`](#createstandardaction)\n    * [`createCustomAction`](#createcustomaction)\n    * [`createAsyncAction`](#createasyncaction)\n  * Action-helpers\n    * [`getType`](#gettype)\n    * [`isActionOf`](#isactionof)\n    * [`isOfType`](#isoftype)\n* [Migration Guides](#migration-guides)\n  * [v1.x.x to v2.x.x](#v1xx-to-v2xx)\n  * [Migrating from redux-actions](#migrating-from-redux-actions)\n* [Compare to others](#compare-to-others)\n  * [redux-actions](#redux-actions)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compatibility Notes\n\n### TypeScript support\n* `typesafe-actions@1.X.X` - minimal TS v2.7\n* `typesafe-actions@2.X.X` - minimal TS v2.9\n* `typesafe-actions@3.X.X` - minimal TS v3.2\n\n### Browser Polyfills\nIf you support older browsers (e.g. IE < 11) and mobile devices please provide this polyfill:\n- [Object.assign](https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Object/assign#Polyfill)\n\nYou could also consider including a global polyfill in your bundled application, such as core-js or babel-polyfill.\nYou can check the `React` guidelines on how to do that, specifically: https://reactjs.org/docs/javascript-environment-requirements.html\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Motivation\n\nWhen I started to combine Redux with TypeScript, I was trying to use [redux-actions](https://redux-actions.js.org/) to reduce the maintainability cost and boilerplate of **action-creators**. Unfortunately, the results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here for a detailed comparison)](#redux-actions).\n\nExisting solutions in the wild have been either **too verbose because of redundant type annotations** (hard to maintain) or **used classes** (hinders readability and requires using the **new** keyword 😱)\n\n**So I created `typesafe-actions` to address all of the above pain points.**\n\nThe core idea was to design an API that would mostly use the power of TypeScript **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition, I wanted to make it \"look and feel\" as close as possible to the idiomatic JavaScript ❤️ , so we don't have to write the redundant type annotations that which will create additional noise in your code.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Behold the Mighty \"Tutorial\"\n\nTo showcase the flexibility and the power of the **type-safety** provided by this library, let's build the most common parts of a typical todo-app using a Redux architecture:\n\n> **WARNING**: Please make sure that you are familiar with the following concepts of programming languages to be able to follow along: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n### - The Constants\n\n**String constants limitation in TypeScript** - when using **string constants** as action `type` property, please make sure to use **simple string literal assignment with const**. This limitation is coming from the type-system, because all the **dynamic string operations** (e.g. string concatenation, template strings and also object used as a map) will widen the literal type to its super-type, `string`. As a result this will break contextual typing for **action** object in reducer cases.\n\n```ts\n// Example file: './constants.ts'\n\n// WARNING: Incorrect usage\nexport const ADD = prefix + 'ADD'; // => string\nexport const ADD = `${prefix}/ADD`; // => string\nexport default {\n   ADD: '@prefix/ADD', // => string\n}\n\n// Correct usage\nexport const ADD = '@prefix/ADD'; // => '@prefix/ADD'\nexport const TOGGLE = '@prefix/TOGGLE'; // => '@prefix/TOGGLE'\nexport default ({\n  ADD: '@prefix/ADD', // => '@prefix/ADD'\n} as const) // working in TS v3.4 and above => https://github.com/Microsoft/TypeScript/pull/29510\n```\n\n### - The Actions\n\nDifferent projects have different needs, and conventions vary across teams, and this is why `typesafe-actions` was designed with flexibility in mind. It provides three different major styles so you can choose whichever would be the best fit for your team.\n\n#### 1. Basic actions\n`action` and `createAction` are creators that can create **actions** with predefined properties ({ type, payload, meta }). This make them concise but also opinionated.\n \nImportant property is that resulting **action-creator** will have a variadic number of arguments and preserve their semantic names `(id, title, amount, etc...)`.\n\nThis two creators are very similar and the only real difference is that `action` **WILL NOT WORK** with **action-helpers**.\n\n```ts\nimport { action, createAction } from 'typesafe-actions';\n\nexport const add = (title: string) => action('todos/ADD', { id: cuid(), title, completed: false });\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n\nexport const add = createAction('todos/ADD', action => {\n  // Note: \"action\" callback does not need \"type\" parameter\n  return (title: string) => action({ id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 2. FSA compliant actions\nThis style is aligned with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action), so your **action** object shape is constrained to `({ type, payload, meta, error })`. It is using **generic type arguments** for `meta` and `payload` to simplify creation of type-safe action-creators.\n\nIt is important to notice that in the resulting **action-creator** arguments are also constrained to the predefined: `(payload, meta)`, making it the most opinionated creator.\n\n> **TIP**: This creator is the most compatible with `redux-actions` in case you are migrating.\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// toggle: (payload: string) => { type: \"todos/TOGGLE\"; payload: string; }\n\nexport const add = createStandardAction('todos/ADD').map(\n  (title: string) => ({\n    payload: { id: cuid(), title, completed: false },\n  })\n);\n// add: (payload: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 3.  Custom actions - all the remaining cases\n\nThis approach will give us the most flexibility of all creators, providing a variadic number of named parameters and custom properties on **action** object to fit all the custom use-cases.\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('todos/ADD', type => {\n  return (title: string) => ({ type, id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; id: string; title: string; completed: boolean; }\n```\n\n> **TIP**: For more examples please check the [API Docs](#table-of-contents).\n\n[⇧ back to top](#table-of-contents)\n\n### - The Action-Helpers\n\nNow I wan't to show you **action-helpers** and explain why they are useful. We're going to implement a side-effect responsible for showing a success toast when the user adds a new todo.\n\n#### with action-creators\n\nInstead of **type-constants** we can use **action-creators** to match actions we are interested it. There is a `isActionOf` helper that will accept **action-creator** parameter and it'll match all actions that was created with this creator.\n\nImportant thing is that this helper is acting as a **type-guard** so it'll narrow **tagged union type** (`RootAction`) to a specific action type that we want.\n\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      toastService.success(...);\n    })\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n#### with type-constants\nAlternatively if your team prefers to use **type-constants**, we have an equivalent helper (`isOfType`) which will accept **type-constants** instead of action-creators and have the exact same behavior.\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isTypeOf(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isTypeOf([ADD, TOGGLE])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n> **TIP:** action-helpers are working in all types of conditional statements.\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - The Async-Flow\n\n#### Starring `redux-observable` epics\n\nTo handle an async-flow of http request lets implement an `epic`. The `epic` will call a remote API using an injected `todosApi` client, which will return a Promise that we'll need to handle by using three different actions that correspond to triggering, success and failure.\n\nTo help us simplify the creation process of necessary action-creators, we'll use `createAsyncAction` function providing us with a nice common interface object `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for **actions** and **action-creators** that would otherwise be written explicitly.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodos = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\n// epics.ts\nimport { fetchTodos } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodos.request)),\n    switchMap(action =>\n      from(todosApi.getAll(action.payload)).pipe(\n        map(fetchTodos.success),\n        catchError(pipe(fetchTodos.failure, of))\n      )\n    );\n```\n\n#### Starring `redux-saga` sagas\nWith sagas it's not possible to achieve the same degree of type-safety as with epics because of limitations coming from `redux-saga` API design.\n\nTypescript issues:\n- [Typescript does not currently infer types resulting from a `yield` statement](https://github.com/Microsoft/TypeScript/issues/2983) so you have to manually assert the type  e.g. `const response: Todo[] = yield call(...`\n\n*Here is the latest recommendation although it's not fully optimal. If you cooked something better, please open an issue so we can share it with the world.*\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodos = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\nfunction* addTodoSaga(action: ReturnType<typeof fetchTodos.request>): Generator {\n    const response: Todo[] = yield call(todosApi.getAll, action.payload);\n\n    yield put(fetchTodos.success(response));\n  } catch (err) {\n    yield put(fetchTodos.failure(err));\n  }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### - The Reducer\n\nHere we'll start by generating a **tagged union type** of actions (`TodosAction`). It's very easy to do using `ActionType` **type-helper** provided by `typesafe-actions`.\n```ts\nimport { ActionType, getType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (`TodosAction` for action type)\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\nNow in switch cases using the `type` property of action (which is a **tagged union type**), we can narrow the type of `TodosAction` in the corresponding code block to a specific action type that we expect.\n```ts\n  switch (action.type) {\n    case getType(todos.add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n> **TIP**: we are using `getType` action-helper with the respective action-creator as an argument for the corresponding switch case. This will help to reduce boilerplate and completely remove the need to use **type-constants**. But if your team prefer to use regular type-constants, you can still use them.\n\nI recommend to create a `RootAction` in the central point of your redux store - it will model a complete representation of all possible action types in your application. You can even merge it with third-party action types as shown below to make your model even more complete.\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\ntype ReactRouterAction = RouterAction | LocationChangeAction;\nimport { TodosAction } from '../features/todos';\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs\n\n### Type-helpers\nBelow helper functions are very flexible generalizations, works great with nested structures and will cover numerous different use-cases.\n\n#### ActionType\n\n_Powerful type-helper that will infer union type from **import * as ...** or **action-creator map** object._\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\n// with \"import * as ...\"\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n// TodosAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n\n// with nested action-creator map case\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    },\n  },\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### StateType\n\n_Powerful type helper that will infer state object type from **reducer function** and **nested/combined reducers**._\n\n_**Redux compatibility**: working with redux@4+ types_\n\n```ts\nimport { combineReducers } from 'redux';\nimport { StateType } from 'typesafe-actions';\n\n// with reducer function\nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\n// with nested/combined reducers\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-creators\n\n#### action\n\n_Simple **action factory function** to simplify creation of type-safe actions._\n\n**WARNING**: This approach will **NOT WORK** with **action-helpers** (such as `getType` and `isActionOf`) because it is creating **action objects** while all the other creator functions are returning **enhanced action-creators**.\n\n```ts\naction(type, payload?, meta?)\n```\n\nExamples:\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst increment = () => action('INCREMENT');\n// { type: 'INCREMENT'; }\n\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string }; }\n\nconst getUsers = (params?: string) =>\n  action('GET_USERS', undefined, params);\n// { type: 'GET_USERS'; meta: string | undefined; }\n```\n\n_**TIP**: Starting from TypeScript v3.4 you can achieve similar results using new `as const` operator._\n\n```ts\nconst increment = () => ({ type: 'INCREMENT' } as const);\n```\n\n#### createAction\n\n_Create an enhanced action-creator with unlimited number of arguments._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have predefined properties `({ type, payload, meta })`\n\n```ts\ncreateAction(type)\ncreateAction(type, actionCallback => {\n  return (namedArg1, namedArg2, ...namedArgN) => actionCallback(payload?, meta?)\n})\n\n_**TIP**: Injected `actionCallback` argument is similar to `action` API but doesn't need the \"type\" parameter_\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// - with type only\nconst increment = createAction('INCREMENT');\ndispatch(increment());\n// { type: 'INCREMENT' };\n\n// - with type and payload\nconst add = createAction('ADD', action => {\n  return (amount: number) => action(amount);\n});\ndispatch(add(10));\n// { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getTodos = createAction('GET_TODOS', action => {\n  return (params: Params) => action(undefined, params);\n});\ndispatch(getTodos('some_meta'));\n// { type: 'GET_TODOS', meta: Params }\n\n// - and finally with type, payload and meta\nconst getTodo = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\ndispatch(getTodo('some_id', 'some_meta'));\n// { type: 'GET_TODO', payload: string, meta: string }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### createStandardAction\n\n_Create an enhanced action-creator compatible with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action) to reduce boilerplate and enforce convention._\n- Resulting action-creator have predefined arguments `(payload, meta)`\n- Returned action object have predefined properties `({ type, payload, meta, error })`\n- But it also contains a `.map()` method that allow to map `(payload, meta)` arguments to a custom action object `({ customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateStandardAction(type)()\ncreateStandardAction(type)<TPayload, TMeta?>()\ncreateStandardAction(type).map((payload, meta) => ({ customProp1, customProp2, ...customPropN }))\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function to accept ZERO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\n// Very concise with use of generic type arguments\n// - with type only\nconst increment = createStandardAction('INCREMENT')();\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // { type: 'INCREMENT' }\n\n// - with type and payload\nconst add = createStandardAction('ADD')<number>();\nadd(10); // { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getData = createStandardAction('GET_DATA')<undefined, string>();\ngetData(undefined, 'meta'); // { type: 'GET_DATA', meta: string }\n\n// - and finally with type, payload and meta\nconst getData = createStandardAction('GET_DATA')<number, string>();\ngetData(1, 'meta'); // { type: 'GET_DATA', payload: number, meta: string }\n\n// Can map payload and meta arguments to a custom action object\nconst notify = createStandardAction('NOTIFY').map(\n  (payload: string, meta: Meta) => ({\n    from: meta.username,\n    message: `${username}: ${payload}`,\n    messageType: meta.type,\n    datetime: new Date(),\n  })\n);\n\ndispatch(notify('Hello!', { username: 'Piotr', type: 'announcement' }));\n// { type: 'NOTIFY', from: string, message: string, messageType: MessageType, datetime: Date }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### createCustomAction\n\n_Create an enhanced action-creator with unlimited number of arguments and custom properties on action object._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have custom properties `({ type, customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateCustomAction(type, type => {\n  return (namedArg1, namedArg2, ...namedArgN) => ({ type, customProp1, customProp2, ...customPropN })\n})\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action-with-type.spec.ts)\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\ndispatch(add(1));\n// { type: \"CUSTOM\"; customProp1: number; customProp2: number; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### createAsyncAction\n\n_Create an object containing three enhanced action-creators to simplify handling of async flows (e.g. network request - request/success/failure)._\n\n```ts\ncreateAsyncAction(\n  requestType, successType, failureType\n)<TRequestPayload, TSuccessPayload, TErrorPayload>\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function to accept ZERO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchUsers = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<string, User[], Error>();\n\ndispatch(fetchUsers.request(params));\n\ndispatch(fetchUsers.success(response));\n\ndispatch(fetchUsers.failure(err));\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-helpers\n\n#### getType\n\n_Get the **type** property value (narrowed to literal type) of given enhanced action-creator._\n\n```ts\ngetType(actionCreator)\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n```ts\nimport { getType, createStandardAction } from 'typesafe-actions';\n\nconst add = createStandardAction('ADD')<number>();\n\n// In switch reducer\nswitch (action.type) {\n  case getType(add):\n    // action type is { type: \"ADD\"; payload: number; }\n    return state + action.payload;\n\n  default:\n    return state;\n}\n\n// or with conditional statements\nif (action.type === getType(add)) {\n  // action type is { type: \"ADD\"; payload: number; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### isActionOf\n\n_Check if action is an instance of given enhanced action-creator(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n\n**NOTE**: ActionCreator type is generated from the `createAction` API. Simple [action](#action) creators throw a `RuntimeError`\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator, action)\n// or as a curried function\nisActionOf(actionCreator)(action)\n// also accepts an array\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN], action)\n// with its curried equivalent\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo, removeTodo } from './todos-actions';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isActionOf(addTodo)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isActionOf([addTodo, removeTodo])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isActionOf(addTodo, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isActionOf([addTodo, removeTodo], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n#### isOfType\n\n_Check if action type property is equal given type-constant(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n```ts\n// can be used as a binary function\nisOfType(type, action)\n// or as curried function\nisOfType(type)(action)\n// also accepts an array\nisOfType([type1, type2, ...typeN], action)\n// with its curried equivalent\nisOfType([type1, type2, ...typeN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD, REMOVE } from './todos-types';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isOfType(ADD)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isOfType([ADD, REMOVE])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isOfType(ADD, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isOfType([ADD, REMOVE], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guides\n\n### v2.x.x to v3.x.x\nv3.x.x API is backward compatible with v2.x.x. You'll only need to update typescript dependency to `> v3.1`.\n\n### v1.x.x to v2.x.x\n> NOTE: `typesafe-actions@1.x.x` should be used with `utility-types@1.x.x` which contains `$call` utility (removed in `utility-types@2.x.x`)\n\nIn v2 we provide `createActionDeprecated` from v1 API to help with incremental migration.\n\n```ts\n// in v1 we created action-creator like this:\nconst getTodo = createAction('GET_TODO',\n  (id: string, meta: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: meta,\n  })\n);\n\ngetTodo('some_id', 'some_meta'); // { type: 'GET_TODO', payload: 'some_id', meta: 'some_meta' }\n\n// in v2 API we offer few different styles - please choose your preference\nconst getTodoNoHelpers = (id: string, meta: string) => action('GET_TODO', id, meta);\n\nconst getTodoWithHelpers = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\n\nconst getTodoFSA = createStandardAction('GET_TODO')<string, string>();\n\nconst getTodoCustom = createStandardAction('GET_TODO').map(\n  ({ id, meta }: { id: string; meta: string; }) => ({\n    payload: id,\n    meta,\n  })\n);\n```\n\n### Migrating from `redux-actions`\n\nIf you're using `redux-actions` you can replace `createAction` with any of the above styles. Currently there is no equivalent of `createActions` function, so it will need to be replaced with individual usages of `createAction`. The resulting hash of actions does not provide inference for the individual values.\n\nAdditionally, if migrating from JS -> TS, you can swap out `redux-actions` action-creators in your `handleActions` with action-creators from `typesafe-actions`. This works because the action creators exposed by `typesafe-actions` provide the `toString` method used by `redux-actions` to match actions to the correct reducer.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common variants of action-creators (with type only, with payload and with payload + meta)\n\nNote: tested with \"@types/redux-actions\": \"2.2.3\"\n\n#### - with type only (no payload)\n\n##### redux-actions\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible)\n\n##### typesafe-actions\n```ts\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n> with `typesafe-actions` there is no excess nullable types and no excess properties and the action \"type\" property is containing a literal type\n\n#### - with payload\n\n##### redux-actions\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n> first the optional `message` parameter is lost, `username` semantic argument name is changed to some generic `t1`, `type` property is widened once again and `payload` is nullable because of broken inference\n\n##### typesafe-actions\n```ts\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n> `typesafe-actions` infer very precise resulting type, notice working optional parameters and semantic argument names are preserved which is really important for great intellisense experience\n\n#### - with payload and meta\n\n##### redux-actions\n```ts\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n> this time we got a completely broken arguments arity with no type-safety because of `any` type with all the earlier issues\n\n##### typesafe-actions\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n> `typesafe-actions` never fail to `any` type, even with this advanced scenario all types are correct and provide complete type-safety and excellent developer experience \n\n[⇧ back to top](#table-of-contents)\n\n---\n\nMIT License\n\nCopyright (c) 2017 Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.3.0-rc","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-l0lXu0RaS30KVv+EvLElP6YYbQIICm1HuCj5Gue1KSQcYJimOfoTB3kfeHBMpObox5R+fLejrIhan0S/L45D2g==","shasum":"189f612b14bdfd6d50feff959848d43e2458093b","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.3.0-rc.tgz","fileCount":40,"unpackedSize":153850,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcoBRbCRA9TVsSAnZWagAAXwgP/iP59jTvjU77DG8ZGEH/\nBzIAFyxAoQCf5cBnFNQdH4LrDtNpcE7EE9NWD7A1SJhU0BGtH4/n+jZICYB8\nPmVrVrHjMOxFfV8dGJ53q0sZ+W/gFQn9TKlBD4clTW6hpJStkoM/Tvc+/ZWb\njAIHNMo0Dy3XqgP9ppWNKTT+J3lNVbZQNqY4ezBymdmy86+NalStf0A2GOHg\ne+2xnjZka4S7hzA2cVNYvoUEf4pJw5TWdSQ+ZC2NvHM+EqVdXivJV9hwSolU\ni7uD4on4gg9o07+n14U/eG64YPec3KV1RvO8LEhBh4225jgqb3ILGzQGqqqF\n3b7dbZa7PVU+sjrUInX280iIUvG7S/AkjGEteUAytqduz5fh1/gR+FPk5hHr\no+LwYffyfi065xQY2Y/6eJwl/EdnhlhyJk6ykXJ1BMXU+x/+MvyHVGhy1nJ3\nf6wEgyINaCC+K4h6ovdn/Cxk/cxMZD0dd1U1nC2IcAszA2CZebLQu76MAYPb\ndaE7z4y2Ln0VHOGvnXipTPnFCTJFd4FZomrTDG2chss1FEwHKSte2NrDpnOf\n+hOs2pEAVuz8R7tUpdhlG+z8g4mcZ16J3Px3W1vUG3SBPs0Zj5FGx7GK9Ol3\nZ3yV+F4iusKKMhYsSZ1p66L7UqwynUwBfYImTQ13Gnmu0r71/eHYsBBf6Yjd\nFyjF\r\n=6dvt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDqr2b6zl9OXQdpyZVMAgIgXXcein74wfzxVU1ki0AczAiEA5NSXxpVVkzpWy0C2KzoNCWgFLG1OoO56HQryZO0raNI="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.3.0-rc_1553994842216_0.05152706543036567"},"_hasShrinkwrap":false},"3.3.0":{"name":"typesafe-actions","version":"3.3.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.2","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.14.0","typescript":"3.4.1"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"1c568b4406731d5c4c8640fcfa9840d4e1ea5139","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.3.0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-Pf5gB1/lbZxnHYZbj6b/62k+AsY+i2o92MiIN0WgdWiCSUkzLab2Vyvh1tDIoqSmasOa09v8+E6IJjg91ME4nw==","shasum":"fd06eebb740e4901a8b261f93f1f0c0e89e17a99","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.3.0.tgz","fileCount":40,"unpackedSize":153807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcoovjCRA9TVsSAnZWagAAQ+gP/003iGN1PbsWDGa/sMZG\nT1Ss0rEDe30Ho2piR+hs/V0G+6cOa5WMVtnYponOvuSOQD1y3KPx5Iu2bgYm\n3aACy8fmVJRMF4CMKLcjw9qbyoY8lTEO4JKJA5Y16cuF6IJ0tAEdRPdkgDK7\nK3eeUeGcI0tuicM9nGyDScraDYqUYBjLUHtRlQWPLKnpbaYoZxOJcsa+odq0\nsEGTC9mtRP1u9EVylhQEciLUE3DVSypdyS9xgIdiTHQJtUM6/3z0MBHNXr1Z\nPo5NT0ak3HrUJxLK9rfARzU/RFedsHMTE5oKthgQUG+7MTd3my53/9ENDUIL\nk3QIdXKu3s3BkkgbUNvr52jv76MjKpANIt6UupEL++7VwTKUhHnT1LGqw/zO\nrn1HrNZJK8FiWF6QnqIyTsYs+pbfXwb9jto+kS6IG4lsT+FmvB5XaWLUHnSA\nz+riyZWY6fHaO29BlX2tggSSdwG8fDajxTgpjrP2eX/jnxFw4YWhSOv1BLak\nMe+KQ+WF6EJ+sOiiQi8FQccJbzaxX2Ta774ycmT0ZLtzmo30XjlLPveL8hHC\n4eUmdPRti2GEJJFA8JC9oflPUaBNu/UoW3VXoAyiUZpo8z+odWYUN6PkSDrV\nO125jlD9aAYU8lvSUombl1tVUxDGiJnjABOZSaTyW1vWIH0uW4Xf52gF+u7w\nHFFJ\r\n=8AlW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEAFm7hDQPT+3je50HcpkVmseFkIO62eqjoSLJaHTaOEAiEA75rGYM9vOr1SheMGvnvsJAMSW9Wr+1Nn4nA65IkONNI="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.3.0_1554156514083_0.4496971822558309"},"_hasShrinkwrap":false},"3.4.0":{"name":"typesafe-actions","version":"3.4.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.2","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.14.0","typescript":"3.4.1"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"664e24fb5bec94e9b3792620162408d6f83fac25","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@3.4.0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-FW6f61NEe8B8vDftLs3vFMLzyROvqlDS6jhbc2j/fPlCZ6MsY3V4bE4i83uPGfy7Kvvq70ePtsb4nPes9ROXqw==","shasum":"cdf925941eafc75a659ebc2d584b673b86a1a5ab","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-3.4.0.tgz","fileCount":40,"unpackedSize":154072,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcpJ7eCRA9TVsSAnZWagAAclgQAJg7wlcqzWjbq+Y6SEsJ\nJWoyTDfZEBsGsQ4hK7eyubfuUurLUau2C5R+rvyfhwonQRpuUCyf9O4ltXwU\ncv3sn+Ujlp48jiBjAl+t1zoTtpXjAuypbDvYYiq1GhTR6uFHy1WwNM+1tjzY\nP0kIh4UZ4wC/6B2BREsAMUaODovYRSpA76VUS24pb67xfDMtof2v9/PRryE1\nbm9iJvJzPXRjA7mx64mlvkj69k4Fj3wXvr8Y2m9Va2VlzZReexMUVBKoxujJ\nXvSbCXrsGzSC1PlSDpyWE+aYQ2l9UKAGpvPBAyUrFLi0dAdypTdbNJDTjW5o\nXa08XhYn2OQ72IFiSE2eC3XqXMmrPf4SGoqu8OMdP9qCj+4DbMliiffLfxGH\n0CzFGySasg8wbgddAifY7juCUKlRTXoR2xI9Cp5QfFNKG6mYYp/fxU3nifxL\nH1bsCGEe4ZCkosDJe7WH8GiRWCVYPsKrr+akJqbILsTN3H10MXWqE3l/ArGv\nP2Q5tc6uDrSlz5QfJ9Zu90pk/DrGAqoCUsWS7ckLGeG4mtmFw8aJPY66clLt\nKC/8q3nd5akt5bsbzUX/4/0Sn8CO9G4wkd+tVRVuwdc8kn2GEvGDc2vgGWyn\nWNsyGgVlVUBguVBbX0Rt8DWfA/IJe8q6OIkz5eu2I1r1LDaKTeIYAEtyWKZ+\nuQwh\r\n=wCe/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHCWVkX6eepDsWNl4xoqEPZxNR006vCmlQ4a0umXOJo/AiA2ut8UzCTrWovSgePEY73T8WbhdJu+T2YLHiuFxWgblQ=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_3.4.0_1554292445888_0.46877141505520115"},"_hasShrinkwrap":false},"4.0.0":{"name":"typesafe-actions","version":"4.0.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease run the following command to fix:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:update":"jest --config jest.config.json -u","test:watch":"jest --config jest.config.json --watch","test-types":"jest --config dts-jest.config.json","test-types:watch":"jest --config dts-jest.config.json --watch","test-types:update":"jest --config dts-jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","ci-check":"npm run lint && npm run tsc && npm run test:update && npm run test-types:update"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.16.4","rollup":"0.59.1","rollup-plugin-commonjs":"9.2.2","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"22.4.6","tslint":"5.14.0","typescript":"3.4.1"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"a14c2cef81d455f2862702389f3f353682da4752","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.0.0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-VWIQZpUgEqddDbNi1c9eq5T6nzQVGP01HA74O4PXnyzDrewBL6L6usSigH8ZEpqmM/pw59BKttXeiCu6bF7RNA==","shasum":"b41aca3538dd4cf51ed7c7f4e6ee3b517a1d6dc8","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.0.0.tgz","fileCount":40,"unpackedSize":154534,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcpKd2CRA9TVsSAnZWagAAIFgP/1lZEYR9RxZChEF+3U6o\nzA51G74KXA6hxW0oGCFkfD2u6j9D6Hckr+51js6fuP4Is+fafuuxJonvyn1b\n0D6Fa2XwYjEdwbudLrxMRZNYLrkfeRoHen+Ehi+lto13BV3ChkA87+M4UBVp\nFXP6k+1ud8/RShUO1EXz1WJqfeOZwktRJLuJ3nAoi3C0M8Fs8U06LzFWK3Cd\ntvYKrHNMF62cc/fLVVfsUmptn9V4hk+D9+UPCuhVtjn8q3lawBMmo+v3LOGZ\n5QDY/BZL1j3ee/2tF634xysTi0XXR1bzb+8eacvgme25K3WwhghpVRKzRSuZ\nv+cJexhyWT08OnKf+ETrcjzrCRbeU3wXUH4JAiJAvCv46kUEeb7Zm+OoB0mv\nGGV75gqFXw/X++e3tZA+01gXSGPRFwz61FP3h6r4JiqmCkEvm8n/6JEhXQPx\nDI+my8HHC24QBNBU21N90718GSoZjC1Lf7jw1F4o2Jvr4kpJL3lyl5SqwvVZ\nHzBcTqkbv3QjvzALF13wBwpZK9u0TxxhBTJ7fXJRQ9uxKWd+kzN3l1f+3TJc\nVfLDfkD5SFFGEKycaulWJSaeXmtYW/SQTSPlzJb0JKUmxxEj2Jd/LOfdB3xx\nUtypraa7bRcRAYF5T0ifgAX9Ak/Lmzw9MUQSKUHVQz0OvhqbVSUaK1BWUn99\nLS6E\r\n=cPwj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCB8Es7ZlJuZ3SKvtAFcD6IAIadVnJE+wWTnbLJtCD3xwIgYmHvyEeP+J7Ermen1tL0M77Cbu/5IfhrE4d8Dpsn5go="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.0.0_1554294645137_0.9137067678158992"},"_hasShrinkwrap":false},"4.1.0":{"name":"typesafe-actions","version":"4.1.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"cp -a dist/. codesandbox/src/typesafe-actions/ && rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.4"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"ce49312800d3d11b4fe9da00f67077cd37d61313","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.1.0","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-OAcTjCqP68Vfo3fEh9aWYKXbAd7Hz1rNrimhj9OPxUhYYbJtjsly89V70uYvobsM9XPMoscGP1R8tUS3b5MIRQ==","shasum":"4ffcdfa8a37ff8a4c7bcbeb53f342bd5de1ac2b0","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.1.0.tgz","fileCount":43,"unpackedSize":351301,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcvPe7CRA9TVsSAnZWagAA0XAP/jRCQH39eHV59Uft5SOt\n3L5fhg8Swg/znKOKt71fGNHp0S1AdiwoYEsW7KmOzb8FKrfGZGhd1/AAhOH7\n248wcbRxIttgpyGzRC+1rTzY+GCGF3TD2AA5S1ANa/nHwneMPyTxYVPaBkyY\n25wqqw9SRZZHfvMp60bxwL35WDQkOk4zn18k6VP39U/k9eJdc/6HOkmiiBBe\nOOazU3nzSoR0wjFhFBAwMf5W85PMI189zTXCf2/zGNqDf24zMjYXKzml+kgJ\nvlo+qsCBG/lwJovCzFMuW5/64rm9OvKKltGeAhRH+zh1bll+O+GqKEuRuPtd\nKfLDhRJF5r5csKKaUEtcKtTmUF2+/GcUtFLs/O82S066Iyy3U3Fp+flwmwiU\n5aXNSJJKgu4uk3C2BIaSWKij8I0exnzAsRvzucP3bjTVhL+lDGiBuqcbidBM\nYV+2DFWRqCdFnRwlEnol6JlJkH/J/crRxcye7MS1XnM4EMtLLpdbMm3QbAkP\nKTtDee3ZzclZUUrXbmsNlJiF656PPnJiNGDASXldoiQ3JCYUuI1RDWEZy/QY\nGEG/5ERcNCQIzTUsh7kNEfNskXzN7i/4EmVCyJUmO7gZ387qvf7mYH8j9RAp\nWk054N2n2utXLZjpTksiDlPXnCcErcihwS84VnfhD6JWtt+zogDsR0EMJkPx\nvK+A\r\n=GRUp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0KuqqGXN1alp1WEkagRsd0tSg4pZKP5t5RoHIgX83PgIhAJ1Aj6VJTLcv62JZWQfGCBNbCcGTYra6H+EjtaTTzwR4"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.1.0_1555888057824_0.8312388107778996"},"_hasShrinkwrap":false},"4.1.1":{"name":"typesafe-actions","version":"4.1.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"cp -a dist/. codesandbox/src/typesafe-actions/ && rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.4"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"cb8a6036ed215cd474a6658fc0e217df0cb46ab4","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.1.1","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-EQpYlITDjgnHDBVBXP5cPdyX8TLQnCCs5akL9IWgrbTn5KWCzgeVomhUwCPTD3DHTntRdWOwtXT6Mmm1+4dwUQ==","shasum":"e351fc08bc88a3687298a37c35735d745a207cc1","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.1.1.tgz","fileCount":43,"unpackedSize":359418,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcvaQ5CRA9TVsSAnZWagAAZZUP/1dX/MpN/hQ8qT6Z74rB\nwawcTtMiYivweH44numsb/XWSjc1PdGBkBVGdMkiairn3NSdtav4TQWohjsn\nK/q/E4GObtd3B/hSZR93y66jKfcKh4s44vdL05N3CX6OgpQpp4SZrXk1w2Gz\njdou7OlNyZ9eQBYzJ4kDbGW//ZtxcGu812Hc1NXvATwCli3PahXAVjkwZyO6\ns/UFZphQ1soKTpX1iKLbc3JHylv00P3TSUjU5qSyJ6IidSxNBm1OPI+XPLgJ\nGSsBQypi1QvJ6WMf4Tz84iURJoiJYJUW2hW6QV5qlZQEB/vHTV9pjoIIC6Uh\nc3MDzW2xJGy9AkPohSHvWirl5Ju4HldbmhD/WqmislWlaIbCQujajyRqMAwO\nXj7s0b9kTWk9kA7lCgLM7Rhpnup1ZhJK/5bPYp1r4qPFp5iZKRRmQmYfRNWM\ntqUYF6iIT76Lr6m42qoUNNSK7GvqWk2zbLlth2hZ7Evk8ylLxCuZYDlyWSX/\nn+XZ2fvCaIwTskCJsKmameO9EQBglroI7UgFIJdjwlUduP9ONNVggpj/Fw2u\nVuOiyKXoEhR4GPw89D7/hTM8oo4YLaOBI39tPDElWaSrwEbNof0VZ47d8TwA\ndys992epBOHJhT3XeqmhHVivDUXuVpec3huCXNu9WFUyR/NMCfn6hvtRO1ci\nNJ0g\r\n=8iwe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1QSB4JcFm7iPZE02ZE/g+6liXOmqrDRyo8yG4eslrawIgB127gspGMtOAdoSI5nv6v5whSsvyZH3WcXbqcovtiAQ="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.1.1_1555932215860_0.6699759475940377"},"_hasShrinkwrap":false},"4.1.2":{"name":"typesafe-actions","version":"4.1.2","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"cp -a dist/. codesandbox/src/typesafe-actions/ && rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.4"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"5feeff1cf1c65ee6e7f35f721697809d829fccb1","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.1.2","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-aLEum/3M/byzbgGPdEdVFCRwmkmOEUu/Ubkls9LTPL/tqT9Dbn8f96RnY5P2zcOTOFw2yZBBVFvrVRDDwSOV1A==","shasum":"a0da5a8e702ad9323f11b9fd70baeb1d74e2e957","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.1.2.tgz","fileCount":43,"unpackedSize":355296,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcvlcNCRA9TVsSAnZWagAA52EP/1ahqdMCHUcB8291nBjQ\nr/R2cGPrIrJCVbWF6WYHJYtdPM8WWy9f1bbmAQJx+jbVkjkMv9uqWXUwCj2U\nCbEMMURZDcZZkQZkacvTRcy+uX0KaY3K8h7UhTXQEEUtWYHdT1lQ/d/eDzBB\nR03XZXo/MFXZlmpsOAimMw5AufOx4+u0YYeLjG1XePZbHY59BaSqh1H/6NJg\nMKjMx3BcSdz5HCkMeilFy7stqvYVS/TnlDgwn2nDyxSUATyE8s9y2wCNBaM9\nSLjeJex1+38YzOt8KxdTtvMLKKlNQw4dx7BdfKLlsRo6DwB/C41BaukdIvwX\nDhlW/cDZHPxDG+58MdIdNWHASLKczs4MVyFHVjOi7qphKDXNEwDO5Grb4lBM\njIHsDtyf+xqRzUzpL9E2KAy9dbzBAuNGwWJd6WZXL9WcwDNG/YIPPDhop0TP\nHhJ3Cy1qE9UqqOcZhGRpdb3BvsyjLjXS2o9Tu3yBAIACsyFLsbE+GVLEZoH7\nhUMHkyi+x4S571rTsXEgHYSptkUgQ8zuT6lEp1QkXiXsdDnOa/Vm2GBi0kkM\nWvhUqXPy56OwgMRqsbkx+i+MGChldGkRRTMzCqd6pQNSEQ7d8XZ0501PHI8f\nOWkHhEgSmKPJIIJuyHeTuQpgybQfgCZdGQcIfrPjnTLMUfmTgEWX7BtUNeT3\nXZKV\r\n=6TWZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJCoPgR3f3unNX93wRhdlYn6ho6cfIqB3W46pGkh+kKAIhAOD0P2HEdQ5MjoyErEI8finvCrvBpbfyqJKN5ybRmd1Y"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.1.2_1555977996606_0.01932149807454331"},"_hasShrinkwrap":false},"4.1.3":{"name":"typesafe-actions","version":"4.1.3","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"cp -a dist/. codesandbox/src/typesafe-actions/ && rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"1.3.1","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.4"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"211310bf66aa94d78ab820f6beede0b631955538","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.1.3","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-hjrag4b0y/RKJt2JOMinVpIKKQrUF5i1KmBOVpmftwXr0exsfPMJUM4weR+QXkepA3ReTUNv6/GD9wXT9RSO6w==","shasum":"8832bd72617dc9dd801787abe651f39e16eca66b","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.1.3.tgz","fileCount":43,"unpackedSize":355278,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcw6AJCRA9TVsSAnZWagAAgy4QAJB8UxLG7FSrOZCMZJ/v\nr+EHSjgrckkskdKGeV6Q4Z3kavCDv3eU1l+cxVXdTMkUGeJk79TJBj9Ij0t3\nG5i5Z0kCIMVXaMimKOlRWT7eww0jZEE4g4NgNZ31JRPsCAs/qxH/taPmIEj6\nzglnaoYwjU6t+ziUH3uaJwubjuFjQOwhec9DJ6X8oR+aOQFCHfCceuT47YkM\niFON8rJ+ToNuULoRx5QtNGHnQpXqiiFb3MnVvlMQTiddW7MEimecFtn+NICq\n4WmvaQ6b2ltmxydbirj0xL2vmB+W18CzG/fZCEP8k1/8jVw5vlJa97mCVhl1\nlDHjPc+PUP+I6BbmtkGwGEhMv3AqLfUvpsCe+f3CJ/Sfze7WZBV/QP5I5D+3\nZf2RaaayJHEcBkjN6KBHejS2GItPA9Ra28IVM7gF0d8yiAWTKA+IjNNGl3UE\nPzOyC3QWZbahAiUSfUvlF2RN+cbCZA6Pcyg6IdK7bnDxzI67LgInmz+lDqWS\ndiY5jYtclz80FcGm3Zb+op1n2muqKwzu9XB31EidiGyvI5xgrM/1pLKsP97G\noqNJsrnW7W8J0Fp4r1d7sLal3y4HTvDr5j0e/a287Oh3XDXG0j4+eEh/nCij\nYUXC8uRjgtDcZixkx4mbwt/jfhnJaJm+Ybhi7ooIQN3Ka4LGVR0lf9wTlBy8\nzz0Y\r\n=O9Nb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjst+wHO5Kiumm3M2tP4OgymxNgiTrVRBoASOmtt87ugIhAL8ZFIXbluStrD8q1gkupI2ryHf6JcjMS6RnPsjuBZDj"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.1.3_1556324360236_0.9936033145471996"},"_hasShrinkwrap":false},"4.1.4":{"name":"typesafe-actions","version":"4.1.4","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.1.0","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.5"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"8a695860912048794c384f05d6270a0d7c22909e","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.1.4","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-3PbZr1rp3LO4s/Nv74eY/eHQg8bsUU/jkyodHJBEeou9bMqLq4YkbgtDgT5DNj1jyMlmlQxcdN18B0hqByykdw==","shasum":"a382c3ee58ce915366585a831cc3bd1f3e75ff87","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.1.4.tgz","fileCount":43,"unpackedSize":356273,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcxGPtCRA9TVsSAnZWagAAjMQP+QDGbVAL78jLIM6cjT5Y\nSmR23zlH36i6zK7WnCq89MEnRXRuiOcy+eF1kmzYv91LRH5rzdB7pr8NoiLm\n1U8dlh+KjMoBgrHqm8LhqOQN27TYvhKsocxtyviqpM6egBuR12vskgD5626D\nee9f9hKKE19MG0YxJCQnLgEIcsykst1uRAPUejcunLgAFXHi1R9O4cd5Uvzi\n5tUD2fDBU7aJa7ExZwQp9d9XuXPJ+SV4lc07HCct41xbdWiItxL9jDmR3bvL\n2NDPJ/7TXVNepqNRBR1se+Vhb7JDgOzRF5LBVgd+LN0Y8iSEyyrmInOyz8DV\ntgU3FFQgiXNonKJvwhoy6iFsKZ6Vl7gn7mQZGbpDeO/9wWnOt5laWXf/r9TG\ndAelSYN3al5DaU2paf4gyAZKLgVRaRRYm5pgVTmTM8ojucrL35bpoHs6NQYm\nVmy0t1887TQwqNCBCpVoGrDQyxupOHiNa0BmvHEYS+D3kwuuB7KKZPkGlJWU\nvcZR8ia4hIHmVnsDw1k2esB+DRm9V+fQCGLOVLDalZHqTJZi88Ej2+AzH2NA\nccLde/9ie72NgClObd4PeiLXEraT8GcniW15J/Fxw6tz8LU/g6QrxlIC8FNV\nMrujfK9jrzEPE8KWV8gUS2sVvjvYZw/1kwDywjb8IURTukJGS4a8LuEkOXPA\nkUpo\r\n=+pYI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAPXuJqd57rMTuQEv1g9l0DIpVLUBDoYWlmQMsrNmdOCAiBeYy2xv+vq0CNa9UjsQla9I1Ht9x667rksv5xP3by7RA=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.1.4_1556374508856_0.5584918447402409"},"_hasShrinkwrap":false},"4.2.0":{"name":"typesafe-actions","version":"4.2.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run pre-push"}},"scripts":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc","ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.1.0","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.5"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"d8869e9296fabde5d6928eece8cfa1721cb84529","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.2.0","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-UuND9OTYOoK47QFwXRpF+ax9r2+bnJ+M//13mBFU7+EB2NN/5ki6ocmYi4jtTjFTr+gRCOTRy6Sr1z6X1MhTOg==","shasum":"96f26d644803790f4b93f0d82ed2d4187bbd8b92","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.2.0.tgz","fileCount":43,"unpackedSize":227367,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcxJ9CCRA9TVsSAnZWagAAHOYP/1GNmnSik7O7wcEsxrXB\nUOFp8KeKeWOjjHYCkHfoZxNuWDlT3RTS7RgTvlugsVxfNeDkDzmR3y3w8Kyu\ngbN0YwZC/4SA8SImpUl07hSjGxm0hGb/AD4Cr2+9k0aWJWkrnyCNBf0DzZnG\nWJzg8l3QqxRh28il1BQuX+CBmmpp4/VUqHDUececuIA7M7FSVtKwQErtz9QV\nu9R4xdWbBXxk0u3w7RCqnrS2vdfQDmtjVNrgCyiKLhqO5kYXZXGRElbW6aQw\nwunZNId5SS08g2JNaNDk7qvWcWSVg0F6Y4Bt79lbOcZNVRNPquew66kfCEPQ\n3cd7PjDIg+QB79B0XDO4aot+7Iz834N+mqwyuTknk0xKuaHm27Nysi5IhvFT\nnGijrfPlWI2kfZzArhNISVfNg8tsoie3u/I94Da1O1qWlK+LVd7zxWEtat06\nIYPgGxXxP6uCoprKta2Ic+JPlW7qXcx/GNSUWn2MdOQVwKh3momUU4nXr19w\nAu5ycLgerS+Dl8rq6fi66gpd1fzPxizEG+PLAKF4oh44Mo1m6ZTvEH7A/+6q\nS92aXR4qzwcJrrsyYK8jKRki260Pl0Czs5iqxCp/Los8J9MKkq3eD8InRl5I\ny7x0axweqKrOToIClXdWYc+j88RVrU2lTZ39xrVLMpwWSgsk4XBuBy3bymRt\n8dQL\r\n=gVif\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDbDNJ9HD4NPuWTijtQwa53nq4mn/HKvjr7Xl6rqYKlNAiAut1+5DrjNUoTm86KPs+pOHAeW3aXLUwJns1ySGkCfDw=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.2.0_1556389697120_0.2646133797959922"},"_hasShrinkwrap":false},"4.2.1":{"name":"typesafe-actions","version":"4.2.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run pre-push"}},"scripts":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc","ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.1.0","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.5"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"db4a9c51316a6cb027cebc735ff9f3a4267c97bf","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.2.1","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-a+HpDcVl+hRxQS3u83vh3X2ga967b/3TwiFbcqlDOkMSsJTFwzahObsGWuTiSISjSvLKrx0ckeYheLUzti4kYw==","shasum":"b794e141abcc05195df20ee340038fbd60ad2262","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.2.1.tgz","fileCount":43,"unpackedSize":215135,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc1CMZCRA9TVsSAnZWagAAs0QP/RlM2iHOnlR+SHvUN3uf\nCPeDJcThGaGLC86JcuE40bOVctoE7xtg6Xvur3jth9Qdn39vT7Dkj9sA1EX/\nj1KyAmSLr4kCXa+Ks+epqJqg1K5PuKx5iarjZ/jiobzqirRoSPntluLU9+3i\n5tjZQsfTUQE8LaIxcXsrl0ThHmyZlt8SNYFgXLf8dEAKBcu2hDci29w0C+S1\nE4GTAUTm8dF+mdIASCUE6wtNbLpWkxx1VvGAfQauhZKfi/2XeaP3Agq4KcZo\n9I1zpD+0C9F0Z8gJQ45rKpsBopCjtFAPBwjS/Kj+71NIdP/qOf30/xVUGI0e\n0mhyGYMIstevz+UqhJKjYheB63d0TZC2KO1q5cLROM62WWIcooRHRN0t9LxZ\nJfTVL3cMdHtcMP2h7JooWxnEdCcQLbXPR1N/6ZNiRIO/vvltFug/BGApK03T\n21veykYAaDMz8CKGNbcauiidNdfR4ncQFWTJFZ6PEivKiUqR7DO/XhcuYoC4\nxLgN/Xv2R3gbiG4lIskYwlHBg1SV7xmly7vDUBJBz9Rbhvz9iye6EzI4Jm5z\nzcVuVOuox1itJNNQUrgNixb7qTY5H+BPE2HU8yPhjw1p8FQ5HtP7quEuQaJb\nsT8GHsF4ho5DRwDRt/R9A1AoMYJOB8dcuPbJkz2lZb5kNI53SOqTh3maUrwf\nu87Q\r\n=mb1h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDfds17DCWsdbC4TS8KEDbafyxASyLKV5/So7IgijKXAgIhAMCfeqKUc1MUAX87AanvgCAfNYY/B55/9zsPmbkh2+qo"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.2.1_1557406488593_0.2563131174949287"},"_hasShrinkwrap":false},"4.3.0":{"name":"typesafe-actions","version":"4.3.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"dist/index.js","module":"dist/index.esm.js","browser":"dist/index.umd.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@types/jest":"21.1.10","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.1.0","jest":"21.2.1","prettier":"1.17.0","rollup":"0.59.1","rollup-plugin-commonjs":"9.3.4","rollup-plugin-filesize":"1.5.0","rollup-plugin-node-resolve":"3.3.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-uglify":"3.0.0","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.5"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"09ecf57926ad3540df499b48f6d51ad2f80e761d","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.3.0","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-b2mPc5qAUWcThq/CNRTp8IbTr6duG0T2k36gVtIRsndR+16XEGjizaFBuA9+C2+gHUfeJ/IKEgneClW5egj9bA==","shasum":"2283870c442b393a37e0f091eb42ff8590419019","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.3.0.tgz","fileCount":43,"unpackedSize":218152,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc2UDvCRA9TVsSAnZWagAAxxQP/3GbOIOD2GETximjcL/c\nFju8GivN45ckQv82O59i9FUVLHmRxPyMOOPMStw9eY7QJG4oeGrfW25XU8PI\nlrhp665NWFvIHiuG12I/QTkCysjLxLDLArAIhKAmF0k8mDkFVCWzN4g0qbAO\nejqYu0YrpHrZbyA1YPNuuy6gY/4OicLYyUIrxpxThx9yXfAoRr3ILOtyteLW\n+5mYyyHFYrb2kfJnnbWPp9qAuAugrtm3jiaAnAu20trIp99F2uf0VkV2RHW5\nWykCCrldwh0KGGAd+VoyQI+4RH8j8B+hacVDmnrNprE6pWo1sNW2VWrlJ4+K\n7SEF4Q5cUBg+f3iIzBGzcn3pfbqtx4X7NG9ige7vq2ZfwItHkupWv7iLKm4N\nvK+gRLTHTkqnzS/AmCIQjFHVuOpQKt8qo12vnZotkmgzgTYql2vVfOdgVqc8\nJwD/0q0g6+mNj6Sd8KAPxTOiUt/3r4LqP/XUrIeVScYl/N7ziHA5K9sjl0IE\nm+MMS7M0CVGBwIf3sDDUNvltp0mowr3dvTuWvQFKmC5MWI/JY1tWDtDkFlTv\nlihepLOkzBqNWJqWbhNGuqgk6rRbS+OMXu0Cis1RCFJXsxpFr40PYefFi566\nc43Z+JcC/yA7nXCsLrC4Nb5WXBAHf12uS0aBBpaf/H+ovjZUvlEX45sw/Rf1\nJ0df\r\n=v22P\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD+gBdvc5P5vvy36f0H9k8/EAwANjWbTXgjGmz2XQM1QwIgRKdWXa6UsgHdmH2q0HYythwvekGeSMEsi64sfev0920="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.3.0_1557741806283_0.008403191210218708"},"_hasShrinkwrap":false},"4.4.0":{"name":"typesafe-actions","version":"4.4.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build"},"dependencies":{},"devDependencies":{"@babel/core":"7.4.4","@babel/preset-env":"7.4.4","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.1","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.3.0","jest":"21.2.1","prettier":"1.17.1","rollup":"1.12.3","rollup-plugin-babel":"4.3.2","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.0","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.8.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"4.0.4","ts-jest":"21.2.4","tslint":"5.16.0","typescript":"3.4.5"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"cefe804776eda7947d6835d7b4c32b4a0817d42c","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.4.0","_nodeVersion":"10.7.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-91ZsGX/Ojo2lMeRCMwrjohzuGQfB6T7VSkn5HkV6ij4Q4Okhe5eeAXAlUY7erI0sNRGSOWCA6L+lH3PkpD/NlA==","shasum":"217320465f5921f438adda1e9ff5da09182bb266","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.4.0.tgz","fileCount":26,"unpackedSize":110507,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc49U9CRA9TVsSAnZWagAAoOYP/2ieyiFHQzowSKTzd1hi\n3jNoSQzweOwcOvefjxZzsasqKwHHR0xmB38D+iVV0/ZhpKARHVnpxySHSkX8\nBDNfMfvmC6XJfGEq2PxlnNH5GKCacjt6u7tDPSZvc05YuBmkvQKy8XzUPgiK\n86tDlpQGiKGkaDQ+Doz9dRN11d/HtgBYgXxFXVY55jw7qNiX1WjPujmtrJCk\nrnsUUGM2UueYsutGgKZ5Z1hxcMoEQnFabxcVWYOVYYEHhpJZzduyQxxcUMN+\nHIkEPUgwPDMtjfhONvAEz+B2RFH95LcT2v5beBf69rWJ6186+MTZbkARQ32a\nQuxtA7jbfdQL7KZgUrmBR+HQzELCHu8+CwDSO+YtToPdpcYq1XT5mcIxz4jB\n4HPdRhpczPvsXfSWxt9shhdnw5Ncemyf/PCmRqUdWc//+Ew7MTk+7sLOIXZV\nR3wIloNaZ/OxRRW625YZ7uOIbYNxvD/t9+Xg2V6SLozNXtEGEALEt3B8TXw5\n/R3+oYADkX+KtJJqGb4XTQvd8terjhNagnQu7D6vkXruD3BvvHLTuR9GM7gg\nGylWZgXeJP5ApiU4Q6FstLvvWCx78iaIuL/O39XSi9dAo504aVOdI9xwdIWc\n4w3seuy8J6iyeZ7zqAP7uESitOYXcIFwIVO140Vs+VnH27UmbCn8IsFAySmy\ncbVj\r\n=zlig\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDYHJbkVNEUpwJbTNipjTJHQ0wP28y4nYmi4+zxa8TCZAIhAKUznnncnqd4gGjeNxcE/eNyFLKDy2WbCMoHjqjEZ5Yq"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.4.0_1558435126154_0.9760819039609097"},"_hasShrinkwrap":false},"4.4.1":{"name":"typesafe-actions","version":"4.4.1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run ci-check"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test && npm run doctoc","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json","test:watch":"jest --config jest.config.json --watch","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename '{{basename}}.snap.{{extname}}'","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:2":"rm -rf out && node --max-old-space-size=8000 ./node_modules/typescript/lib/tsc.js --diagnostics --outDir out benchmarks/2-actions.ts","benchmark:10":"rm -rf out && node --max-old-space-size=8000 ./node_modules/typescript/lib/tsc.js --diagnostics --outDir out benchmarks/10-actions.ts","benchmark:50":"rm -rf out && node --max-old-space-size=8000 ./node_modules/typescript/lib/tsc.js --diagnostics --outDir out benchmarks/50-actions.ts"},"dependencies":{},"devDependencies":{"@babel/core":"7.4.4","@babel/preset-env":"7.4.4","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.3","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.4.1","jest":"21.2.1","prettier":"1.18.2","rollup":"1.15.4","rollup-plugin-babel":"4.3.2","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.2","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.9.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.0.0","ts-jest":"21.2.4","tslint":"5.17.0","typescript":"3.5.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"2aa2ab6e376c38461bc51591d5fdf21cf2e4448b","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.4.1","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-uV74N8uDU2lVaNnYUGmg/Th/mPi9JQJJ5A8+YcHBE5GI+bdgFyl79zCZw4LLU331GCdHWDo6F2J7LVgBHRvaGQ==","shasum":"92e4348289d932592f1f18c162f5c094aba8fe9a","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.4.1.tgz","fileCount":26,"unpackedSize":110409,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdA83GCRA9TVsSAnZWagAAAXMP/Azi1+BQpHDgOUGt/Qe1\n/0/DYUvaed5Q/mIKnH5QdgE/SYV8UzVQTbBITW1QPCTbeUIu2sLef5Acfb2g\nKCy+ZgARMlID5UC5ns9/3maMJpWv+bnAVk4SrFp+Cbe4ZH5QlTlzcj3RgBeE\niono24KBkB04WbsaWiNTgvUzWs7fWtc++/JdVTpubH/G4K4GieB7RqpIVf8e\nhvMa2XWiZuZHS/okvVJiPFoy1TtpqBvEhHu3i1u4b1ws4ioGyDXv5L2LDm6G\nqUwSZX7HZ1E/gn/qUbjLj1HzeNHy2s26Cr/YswQ84CPbtCXBWDmviWDM6oiF\njhkIA4pOxffAN7WYFA6fZvUU5FzR0qqvgcyzK5ogyFyq1mkH1OYsua40qKDY\nRL79ZtBB9OaV5adhYaf+zGIRfJ/K8XrulLAwZ8QSfKs32tuwnfPQKjdnuVfi\nGI/5ldU43lphiT0lIrJa/+pczBiQDa3cLlxG12Y2jG7ftv/NaVMuz8twV/9A\nn8A3a01gSErXBU43f0gn7toUnwjYEErOUZwacpCEhbGWQYMSPDT9W9hf8VUU\nYauHutxxqWFegY5XG+n1g1Sri2PcvpF/ghNJvceNVmNpcd2wZtuzWAUFMv58\nmfXXf4tprNZiJZ4ZCN3Bmo/tak2/qQdcMfGDnlBiCETr4n2WM2wfw+MkQerZ\nGV9a\r\n=F1fM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCUoAsEITMz9Kqp3YUAJh3mYnP+Rwo7MzBYk/chXddLSQIgZyrEJYC1BbiCw0rvMifB20qQZY4mzM10haF0FcETGXE="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.4.1_1560530373185_0.7039869022442633"},"_hasShrinkwrap":false},"4.4.2":{"name":"typesafe-actions","version":"4.4.2","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:2":" node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/2-actions.ts && rm -rf out","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:50":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/50-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.4.1","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.9.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.0.0","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.5.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"18e6de6cc5365bdccd6c6594139b1caab47d0a12","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@4.4.2","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-QW61P4cOX8dCNmrfpcUMjvU/MF/sFTC8/PlG9215W1gKDzZUBjRGdyYSO6ZcEUNsn491S2VpryJOHSIVSDqJrg==","shasum":"8f817c479d12130b5ebb442032968b2a18929e1a","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-4.4.2.tgz","fileCount":26,"unpackedSize":111001,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdD6IyCRA9TVsSAnZWagAAJQ8QAJw9Xgmey2mf5eeLwWK2\n6TKq+ZQxk92JeYG8VfwFCDkkACCN27ZuPtRoa5LHy5LHoxyBawK62sDOF4RJ\nE4tlqTtGImZK308BGtC7/VXNHBO86MuLsh8D9ZJKG9/tRh0dk0iTIl/ZVDjE\nsGu4wG1fzv8G5pIK2Q8v+Ph4XhtPnAbFN05DgHls/IZsVWaYtbSi4um+UMD1\nHDNBUCisr/1rL+fZWlpcGJ4U1AjbfjolgJBckPHGGu4LxmDtcVnRSGR7Yz0U\nCKQzcmZIPhWoCPBwR/6H+IiflgdW0K4ZDS9iDCk8nP6xj1g4pQnv4QoTh/v5\nquxIVwPMwhQEAjILUTBgDw2ANQ0JsZmM+Os/NLj1lNfSb6p5u6ITt7aPR/wC\nfVQWERKuX7igyD/kAOAQy17riBKQqLGvSZzdLiKpTVB4z2qvLz3nzbFlHUFc\nwplqbk+sD09Aa20tLq67wLZDLYV6zxX7hDJedphbqmw4kHKmWoNWF3KugbA2\nKYEKQBrPuI56PdpciJU9OUcngIzhHJxjxD0CzNVPey8+Og4X294XxqPY5jKc\n8N6RVHGqCg9N8MQQt5X0Pwmy8pGluBlEKNj3WJX9Hb76Jw5JfSh4zo/SmK3x\n3W/IRIit+/5VpS7gLy8CCfpwKi5qInRB+JTD9WBiJ6z8L1WKImhHyG3y0/oH\nlQwS\r\n=6Umh\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIH1w37DZLJEqs1kbdMQBORzQnG/pEG85sXrzhKjQ8ue5AiBrgJ1H9xk8iyYnavFhwUercPJNVA/5qigcDPXh27S+dA=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_4.4.2_1561305649602_0.8355974384761826"},"_hasShrinkwrap":false},"5.0.0-0":{"name":"typesafe-actions","version":"5.0.0-0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.4.1","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.9.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.0.0","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.5.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"5cceee89812a1e1e0ceaae8ff0f958ac9df80722","readme":"<div align=\"center\">\n\n# typesafe-actions\n\nTypesafe utilities designed to reduce types **verbosity**\nand **complexity**  in Redux Architecture.\n\n_This library is part of the [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)_ ecosystem :book:  \n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Build Status](https://semaphoreci.com/api/v1/piotrekwitek/typesafe-actions/branches/master/shields_badge.svg)](https://semaphoreci.com/piotrekwitek/typesafe-actions)\n[![dependencies Status](https://david-dm.org/piotrwitek/typesafe-actions/status.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![License](https://img.shields.io/npm/l/typesafe-actions.svg?style=flat)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Bundlephobia Size](https://img.shields.io/bundlephobia/minzip/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n:star: _Found it useful? Want more updates?_ [**Show your support by giving a :star:**](https://github.com/piotrwitek/typesafe-actions/stargazers)\n\n:tada: _Now updated to support **TypeScript v3.5**_ :tada:\n\n<a href=\"https://www.buymeacoffee.com/zh9guxbA5\">\n  <img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me a Coffee\">\n</a>\n<a href=\"https://www.patreon.com/piotrekwitek\">\n  <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button@2x.png\" alt=\"Become a Patron\" width=\"160\">\n</a>\n\n</div>\n\n---\n\n**Features**\n\n- **minimalistic** - according to `size-snapshot` (Minified: 3.48 KB, Gzipped: 1.03 KB), check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n- **secure and optimized** - no external dependencies, bundled in 3 different formats (`cjs`, `esm` and `umd` for browser) with separate optimized bundles for dev & prod (same as `react`)\n- **focus on quality** - complete test-suite for an entire API surface containing regular runtime tests and extra type-tests to guarantee **type soundness** and to prevent regressions in the future TypeScript versions\n- **focus on performance** - integrated performance benchmarks to guarantee that the computational complexity of types are in check and there are no slow-downs when your application grow `npm run benchmark:XXX`\n\n\n**Codesandbox links**\n\n- Reference Todo-App implementation using `typesafe-actions`: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n- Starter to help reproduce bug reports: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n\n---\n\n## Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [Motivation](#motivation)\n- [Installation](#installation)\n- [Compatibility Notes](#compatibility-notes)\n- [Contributing Guide](#contributing-guide)\n- [Funding](#funding)\n- [Tutorial](#tutorial)\n  - [Constants](#constants)\n  - [Actions](#actions)\n    - [1. Basic actions](#1-basic-actions)\n    - [2. FSA compliant actions](#2-fsa-compliant-actions)\n    - [3. Custom actions (non-standard use-cases)](#3-custom-actions-non-standard-use-cases)\n  - [Action Helpers](#action-helpers)\n    - [Using action-creators instances instead of type-constants](#using-action-creators-instances-instead-of-type-constants)\n    - [Using regular type-constants](#using-regular-type-constants)\n  - [Reducers](#reducers)\n    - [Extending internal types to enable type-free syntax with `createReducer`](#extending-internal-types-to-enable-type-free-syntax-with-createreducer)\n    - [Using createReducer API with type-free syntax](#using-createreducer-api-with-type-free-syntax)\n    - [Alternative usage with regular switch reducer](#alternative-usage-with-regular-switch-reducer)\n  - [Async-Flows](#async-flows)\n    - [With `redux-observable` epics](#with-redux-observable-epics)\n    - [With `redux-saga` sagas](#with-redux-saga-sagas)\n- [API Docs](#api-docs)\n  - [Action-Creators API](#action-creators-api)\n    - [`action`](#action)\n    - [`createAction`](#createaction)\n    - [`createStandardAction`](#createstandardaction)\n    - [`createCustomAction`](#createcustomaction)\n    - [`createAsyncAction`](#createasyncaction)\n  - [Reducer-Creators API](#reducer-creators-api)\n    - [`createReducer`](#createreducer)\n  - [Action-Helpers API](#action-helpers-api)\n    - [`getType`](#gettype)\n    - [`isActionOf`](#isactionof)\n    - [`isOfType`](#isoftype)\n  - [Type-Helpers API](#type-helpers-api)\n    - [`ActionType`](#actiontype)\n    - [`StateType`](#statetype)\n- [Migration Guides](#migration-guides)\n  - [`v3.x.x` to `v4.x.x`](#v3xx-to-v4xx)\n  - [`v2.x.x` to `v3.x.x`](#v2xx-to-v3xx)\n  - [`v1.x.x` to `v2.x.x`](#v1xx-to-v2xx)\n  - [Migrating from `redux-actions` to `typesafe-actions`](#migrating-from-redux-actions-to-typesafe-actions)\n- [Recipes](#recipes)\n  - [Restrict Meta type in `action` creator](#restrict-meta-type-in-action-creator)\n- [Compare to others](#compare-to-others)\n  - [`redux-actions`](#redux-actions)\n- [MIT License](#mit-license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n--- \n\n## Motivation\n\nWhen I started to combine Redux with TypeScript, I was trying to use [redux-actions](https://redux-actions.js.org/) to reduce the maintainability cost and boilerplate of **action-creators**. Unfortunately, the results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here for a detailed comparison)](#redux-actions).\n\nExisting solutions in the wild have been either **too verbose because of redundant type annotations** (hard to maintain) or **used classes** (hinders readability and requires using the **new** keyword 😱)\n\n**So I created `typesafe-actions` to address all of the above pain points.**\n\nThe core idea was to design an API that would mostly use the power of TypeScript **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition, I wanted to make it \"look and feel\" as close as possible to the idiomatic JavaScript ❤️ , so we don't have to write the redundant type annotations that which will create additional noise in your code.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compatibility Notes\n\n**TypeScript support**\n\n- `typesafe-actions@1.X.X` - minimal TS v2.7\n- `typesafe-actions@2.X.X` - minimal TS v2.9\n- `typesafe-actions@3.X.X` - minimal TS v3.2\n- `typesafe-actions@4.X.X` - minimal TS v3.2\n\n**Browser support**\n\nIt's compatible with all modern browsers.\n\nFor older browsers support (e.g. IE <= 11) and some mobile devices you need to provide the following polyfills:\n- [Object.assign](https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Object/assign#Polyfill)\n- [Array.prototype.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)\n\n**Recommended polyfill for IE**\n\nTo provide the best compatibility please include a popular polyfill package in your application, such as `core-js` or `react-app-polyfill` for `create-react-app`.\nPlease check the `React` guidelines to learn how to do that: [LINK](https://reactjs.org/docs/javascript-environment-requirements.html)\nA polyfill fo IE11 is included in our `/codesandbox` application.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Contributing Guide\n\nWe are open for contributions. If you're planning to contribute please make sure to read the contributing guide: [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Funding\n**Typesafe-Actions** is an independent open-source project created by people investing their free time for the benefit of our community.\n\nIf you are using **Typesafe-Actions** please consider donating as this will guarantee the project will be updated and maintained in the long run.\n\nIssues can be funded by anyone interested in them being resolved. Reward will be transparently distributed to the contributor handling the task through the IssueHunt platform.\n\n[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/110746954)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the flexibility and the power of the **type-safety** provided by this library, let's build the most common parts of a typical todo-app using a Redux architecture:\n\n> **WARNING**  \n> Please make sure that you are familiar with the following concepts of programming languages to be able to follow along: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n[⇧ back to top](#table-of-contents)\n\n### Constants\n\n> **RECOMMENDATION:**  \n> When using `typesafe-actions` in your project you won't need to export and reuse **string constants**. It's because **action-creators** created by this library have static property with **action type** that you can easily access using **actions-helpers** and then use it in reducers, epics, sagas, and basically any other place. This will simplify your codebase and remove some boilerplate code associated with the usage of **string constants**. Check our `/codesandbox` application to learn some best-practices to create such codebase.\n\n**Limitations of TypeScript when working with string constants** - when using **string constants** as action `type` property, please make sure to use **simple string literal assignment with const**. This limitation is coming from the type-system, because all the **dynamic string operations** (e.g. string concatenation, template strings and also object used as a map) will widen the literal type to its super-type, `string`. As a result this will break contextual typing for **action** object in reducer cases.\n\n```ts\n// Example file: './constants.ts'\n\n// WARNING: Incorrect usage\nexport const ADD = prefix + 'ADD'; // => string\nexport const ADD = `${prefix}/ADD`; // => string\nexport default {\n   ADD: '@prefix/ADD', // => string\n}\n\n// Correct usage\nexport const ADD = '@prefix/ADD'; // => '@prefix/ADD'\nexport const TOGGLE = '@prefix/TOGGLE'; // => '@prefix/TOGGLE'\nexport default ({\n  ADD: '@prefix/ADD', // => '@prefix/ADD'\n} as const) // working in TS v3.4 and above => https://github.com/Microsoft/TypeScript/pull/29510\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Actions\n\nDifferent projects have different needs, and conventions vary across teams, and this is why `typesafe-actions` was designed with flexibility in mind. It provides three different major styles so you can choose whichever would be the best fit for your team.\n\n#### 1. Basic actions\n`action` and `createAction` are creators that can create **actions** with predefined properties ({ type, payload, meta }). This make them concise but also opinionated.\n \nImportant property is that resulting **action-creator** will have a variadic number of arguments and preserve their semantic names `(id, title, amount, etc...)`.\n\nThis two creators are very similar and the only real difference is that `action` **WILL NOT WORK** with **action-helpers**.\n\n```ts\nimport { action, createAction } from 'typesafe-actions';\n\nexport const add = (title: string) => action('todos/ADD', { id: cuid(), title, completed: false });\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n\nexport const add = createAction('todos/ADD', action => {\n  // Note: \"action\" callback does not need \"type\" parameter\n  return (title: string) => action({ id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 2. FSA compliant actions\nThis style is aligned with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action), so your **action** object shape is constrained to `({ type, payload, meta, error })`. It is using **generic type arguments** for `meta` and `payload` to simplify creation of type-safe action-creators.\n\nIt is important to notice that in the resulting **action-creator** arguments are also constrained to the predefined: `(payload, meta)`, making it the most opinionated creator.\n\n> **TIP**: This creator is the most compatible with `redux-actions` in case you are migrating.\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// toggle: (payload: string) => { type: \"todos/TOGGLE\"; payload: string; }\n\nexport const add = createStandardAction('todos/ADD').map(\n  (title: string) => ({\n    payload: { id: cuid(), title, completed: false },\n  })\n);\n// add: (payload: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 3. Custom actions (non-standard use-cases)\n\nThis approach will give us the most flexibility of all creators, providing a variadic number of named parameters and custom properties on **action** object to fit all the custom use-cases.\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('todos/ADD', type => {\n  return (title: string) => ({ type, id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; id: string; title: string; completed: boolean; }\n```\n\n> **TIP**: For more examples please check the [API Docs](#table-of-contents).\n\n> **RECOMMENDATION**  \n> Common approach is to create a `RootAction` in the central point of your redux store - it will represent all possible action types in your application. You can even merge it with third-party action types as shown below to make your model complete.\n\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\nimport { TodosAction } from '../features/todos';\n\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Action Helpers\n\nNow I want to show you **action-helpers** and explain their use-cases. We're going to implement a side-effect responsible for showing a success toast when user adds a new todo.\n\nImportant thing to notice is that all these helpers are acting as a **type-guard** so they'll narrow **tagged union type** (`RootAction`) to a specific action type that we want.\n\n#### Using action-creators instances instead of type-constants\n\nInstead of **type-constants** we can use **action-creators** instance to match specific actions in reducers and epics cases. It works by adding a static property on **action-creator** instance which contains the `type` string. \n\nThe most common one is `getType`, which is useful for regular reducer switch cases:\n\n```ts\n  switch (action.type) {\n    case getType(todos.add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\nThen we have the `isActionOf` helper which accept **action-creator** as first parameter matching actions with corresponding type passed as second parameter (it's a curried function).\n\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      toastService.success(...);\n    })\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n#### Using regular type-constants\nAlternatively if your team prefers to use regular **type-constants** you can still do that.\n\nWe have an equivalent helper (`isOfType`) which accept **type-constants** as parameter providing the same functionality.\n\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isOfType(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isOfType([ADD, TOGGLE])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n> **TIP:** you can use action-helpers with other types of conditional statements.\n\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Reducers\n\n#### Extending internal types to enable type-free syntax with `createReducer`\n\nWe can extend internal types of `typesafe-actions` module with `RootAction` definition of our application so that you don't need to pass generic type arguments with `createReducer` API:\n\n```ts\n// types.d.ts\nimport { StateType, ActionType } from 'typesafe-actions';\n\nexport type RootAction = ActionType<typeof import('./actions').default>;\n\ndeclare module 'typesafe-actions' {\n  interface Types {\n    RootAction: RootAction;\n  }\n}\n\n// now you can use\ncreateReducer(...)\n// instead of\ncreateReducer<State, Action>(...)\n```\n\n#### Using createReducer API with type-free syntax\n\nWe can prevent a lot of boilerplate code and type errors using this powerfull and completely typesafe API.\n\nUsing handleAction chain API:\n```ts\n// using action-creators\nconst counterReducer = createReducer(0)\n  // state and action type is automatically inferred and return type is validated to be exact type\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(add, ... // <= error is shown on duplicated or invalid actions\n  .handleAction(increment, (state, _) => state + 1)\n  .handleAction(... // <= error is shown when all actions are handled\n  \n  // or handle multiple actions using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer(0)\n  .handleAction('ADD', (state, action) => state + action.payload)\n  .handleAction('INCREMENT', (state, _) => state + 1);\n  \ncounterReducer(0, add(4)); // => 4\ncounterReducer(0, increment()); // => 1\n```\n\n#### Alternative usage with regular switch reducer\n\nFirst we need to start by generating a **tagged union type** of actions (`TodosAction`). It's very easy to do by using `ActionType` **type-helper**.\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\n\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (`TodosAction` for action type).\n\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\n\nNow in the switch cases we can use the `type` property of action to narrowing the union type of `TodosAction` to an action that is corresponding to that type.\n\n```ts\n  switch (action.type) {\n    case getType(add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Async-Flows\n\n#### With `redux-observable` epics\n\nTo handle an async-flow of http request lets implement an `epic`. The `epic` will call a remote API using an injected `todosApi` client, which will return a Promise that we'll need to handle by using three different actions that correspond to triggering, success and failure.\n\nTo help us simplify the creation process of necessary action-creators, we'll use `createAsyncAction` function providing us with a nice common interface object `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for **actions** and **action-creators** that would otherwise be written explicitly.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE',\n  'FETCH_TODOS_CANCEL'\n)<string, Todo[], Error, string>();\n\n// epics.ts\nimport { fetchTodosAsync } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodosAsync.request)),\n    switchMap(action =>\n      from(todosApi.getAll(action.payload)).pipe(\n        map(fetchTodosAsync.success),\n        catchError(pipe(fetchTodosAsync.failure, of)),\n        takeUntil(action$.pipe(filter(isActionOf(fetchTodosAsync.cancel)))),\n      )\n    );\n```\n\n#### With `redux-saga` sagas\nWith sagas it's not possible to achieve the same degree of type-safety as with epics because of limitations coming from `redux-saga` API design.\n\nTypescript issues:\n- [Typescript does not currently infer types resulting from a `yield` statement](https://github.com/Microsoft/TypeScript/issues/2983) so you have to manually assert the type  e.g. `const response: Todo[] = yield call(...`\n\n*Here is the latest recommendation although it's not fully optimal. If you managed to cook something better, please open an issue to share your finding with us.*\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\nfunction* addTodoSaga(action: ReturnType<typeof fetchTodosAsync.request>): Generator {\n    const response: Todo[] = yield call(todosApi.getAll, action.payload);\n\n    yield put(fetchTodosAsync.success(response));\n  } catch (err) {\n    yield put(fetchTodosAsync.failure(err));\n  }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs\n\n### Action-Creators API\n\n#### `action`\n\n_Simple **action factory function** to simplify creation of type-safe actions._\n\n> **WARNING**:  \n> This approach will **NOT WORK** with **action-helpers** (such as `getType` and `isActionOf`) because it is creating **action objects** while all the other creator functions are returning **enhanced action-creators**.\n\n```ts\naction(type, payload?, meta?, error?)\n```\n\nExamples:\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst increment = () => action('INCREMENT');\n// { type: 'INCREMENT'; }\n\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string }; }\n\nconst getUsers = (params?: string) =>\n  action('GET_USERS', undefined, params);\n// { type: 'GET_USERS'; meta: string | undefined; }\n```\n\n> **TIP**: Starting from TypeScript v3.4 you can achieve similar results using new `as const` operator.\n\n```ts\nconst increment = () => ({ type: 'INCREMENT' } as const);\n```\n\n#### `createAction`\n\n_Create an enhanced action-creator with unlimited number of arguments._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have predefined properties `({ type, payload, meta })`\n\n```ts\ncreateAction(type)\ncreateAction(type, actionCallback => {\n  return (namedArg1, namedArg2, ...namedArgN) => actionCallback(payload?, meta?)\n})\n```\n> **TIP**: Injected `actionCallback` argument is similar to `action` API but doesn't need the \"type\" parameter\n\nExamples:\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// - with type only\nconst increment = createAction('INCREMENT');\ndispatch(increment());\n// { type: 'INCREMENT' };\n\n// - with type and payload\nconst add = createAction('ADD', action => {\n  return (amount: number) => action(amount);\n});\ndispatch(add(10));\n// { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getTodos = createAction('GET_TODOS', action => {\n  return (params: Params) => action(undefined, params);\n});\ndispatch(getTodos('some_meta'));\n// { type: 'GET_TODOS', meta: Params }\n\n// - and finally with type, payload and meta\nconst getTodo = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\ndispatch(getTodo('some_id', 'some_meta'));\n// { type: 'GET_TODO', payload: string, meta: string }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createStandardAction`\n\n_Create an enhanced action-creator compatible with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action) to reduce boilerplate and enforce convention._\n- Resulting action-creator have predefined arguments `(payload, meta)`\n- Returned action object have predefined properties `({ type, payload, meta, error })`\n- But it also contains a `.map()` method that allow to map `(payload, meta)` arguments to a custom action object `({ customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateStandardAction(type)()\ncreateStandardAction(type)<TPayload, TMeta?>()\ncreateStandardAction(type).map((payload, meta) => ({ customProp1, customProp2, ...customPropN }))\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\n// Very concise with use of generic type arguments\n// - with type only\nconst increment = createStandardAction('INCREMENT')();\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // { type: 'INCREMENT' } (no parameters are required)\n\n\n// - with type and payload\nconst add = createStandardAction('ADD')<number>();\nadd(10); // { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getData = createStandardAction('GET_DATA')<undefined, string>();\ngetData(undefined, 'meta'); // { type: 'GET_DATA', meta: string }\n\n// - and finally with type, payload and meta\nconst getData = createStandardAction('GET_DATA')<number, string>();\ngetData(1, 'meta'); // { type: 'GET_DATA', payload: number, meta: string }\n\n// Can map payload and meta arguments to a custom action object\nconst notify = createStandardAction('NOTIFY').map(\n  (payload: string, meta: Meta) => ({\n    from: meta.username,\n    message: `${username}: ${payload}`,\n    messageType: meta.type,\n    datetime: new Date(),\n  })\n);\n\ndispatch(notify('Hello!', { username: 'Piotr', type: 'announcement' }));\n// { type: 'NOTIFY', from: string, message: string, messageType: MessageType, datetime: Date }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createCustomAction`\n\n_Create an enhanced action-creator with unlimited number of arguments and custom properties on action object._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have custom properties `({ type, customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateCustomAction(type, type => {\n  return (namedArg1, namedArg2, ...namedArgN) => ({ type, customProp1, customProp2, ...customPropN })\n})\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action-with-type.spec.ts)\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\ndispatch(add(1));\n// { type: \"CUSTOM\"; customProp1: number; customProp2: number; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createAsyncAction`\n\n_Create an object containing three enhanced action-creators to simplify handling of async flows (e.g. network request - request/success/failure)._\n\n```ts\ncreateAsyncAction(\n  requestType, successType, failureType, cancelType?\n)<TRequestPayload, TSuccessPayload, TFailurePayload, TCancelPayload?>()\n```\n\n##### `AsyncActionCreator`\n\n```ts\ntype AsyncActionCreator<\n  [TRequestType, TRequestPayload],\n  [TSuccessType, TSuccessPayload],\n  [TFailureType, TFailurePayload],\n  [TCancelType, TCancelPayload]?\n> = {\n  request: StandardActionCreator<TRequestType, TRequestPayload>,\n  success: StandardActionCreator<TSuccessType, TSuccessPayload>,\n  failure: StandardActionCreator<TFailureType, TFailurePayload>,\n  cancel?: StandardActionCreator<TCancelType, TCancelPayload>,\n}\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction, AsyncActionCreator } from 'typesafe-actions';\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<string, User[], Error>();\n\ndispatch(fetchUsersAsync.request(params));\n\ndispatch(fetchUsersAsync.success(response));\n\ndispatch(fetchUsersAsync.failure(err));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error]\n  >\n) => a;\nfn(fetchUsersAsync);\n\n// There is 4th optional argument to declare cancel action\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n  'FETCH_USERS_CANCEL'\n)<string, User[], Error, string>();\n\ndispatch(fetchUsersAsync.cancel('reason'));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error],\n    ['FETCH_USERS_CANCEL', string]\n  >\n) => a;\nfn(fetchUsersAsync);\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Reducer-Creators API\n\n#### `createReducer`\n\n_Create a typesafe reducer_\n\n```ts\ncreateReducer<TState, TRootAction>(initialState, handlersMap?)\n// or\ncreateReducer<TState, TRootAction>(initialState)\n  .handleAction(actionCreator, reducer)\n  .handleAction([actionCreator1, actionCreator2, ...actionCreatorN], reducer)\n  .handleType(type, reducer)\n  .handleType([type1, type2, ...typeN], reducer)\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-reducer.spec.ts)\n\n> **TIP:** You can use reducer API with a **type-free** syntax by [Extending internal types](#extending-internal-types-to-enable-type-free-syntax-with-createreducer), otherwise you'll have to pass generic type arguments like in below examples\n```ts\n// type-free syntax doesn't require generic type arguments\nconst counterReducer = createReducer(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Object map style:**\n```ts\nimport { createReducer, getType } from 'typesafe-actions'\n\ntype State = number;\ntype Action = { type: 'ADD', payload: number } | { type: 'INCREMENT' };\n\nconst counterReducer = createReducer<State, Action>(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Chain API style:**\n```ts\n// using action-creators\nconst counterReducer = createReducer<State, Action>(0)\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(increment, (state, _) => state + 1)\n\n  // handle multiple actions by using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer<State, Action>(0)\n  .handleType('ADD', (state, action) => state + action.payload)\n  .handleType('INCREMENT', (state, _) => state + 1);\n```\n\n**Extend or compose reducers - every operation is completely typesafe:**\n```ts\nconst newCounterReducer = createReducer<State, Action>(0)\n  .handleAction('SUBTRACT', (state, action) => state - action.payload)\n  .handleAction('DECREMENT', (state, _) => state - 1);\n\nconst bigReducer = createReducer<State, Action>(0, {\n  ...counterReducer.handlers, // typesafe\n  ...newCounterReducer.handlers, // typesafe\n  SUBTRACT: decrementReducer.handlers.DECREMENT, // <= error, wrong type\n})\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-Helpers API\n\n#### `getType`\n\n_Get the **type** property value (narrowed to literal type) of given enhanced action-creator._\n\n```ts\ngetType(actionCreator)\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n```ts\nimport { getType, createStandardAction } from 'typesafe-actions';\n\nconst add = createStandardAction('ADD')<number>();\n\n// In switch reducer\nswitch (action.type) {\n  case getType(add):\n    // action type is { type: \"ADD\"; payload: number; }\n    return state + action.payload;\n\n  default:\n    return state;\n}\n\n// or with conditional statements\nif (action.type === getType(add)) {\n  // action type is { type: \"ADD\"; payload: number; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isActionOf`\n\n_Check if action is an instance of given enhanced action-creator(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n\n> **WARNING**: Regular action creators and [action](#action) will not work with this helper\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator, action)\n// or as a curried function\nisActionOf(actionCreator)(action)\n// also accepts an array\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN], action)\n// with its curried equivalent\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo, removeTodo } from './todos-actions';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isActionOf(addTodo)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isActionOf([addTodo, removeTodo])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isActionOf(addTodo, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isActionOf([addTodo, removeTodo], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isOfType`\n\n_Check if action type property is equal given type-constant(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n```ts\n// can be used as a binary function\nisOfType(type, action)\n// or as curried function\nisOfType(type)(action)\n// also accepts an array\nisOfType([type1, type2, ...typeN], action)\n// with its curried equivalent\nisOfType([type1, type2, ...typeN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD, REMOVE } from './todos-types';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isOfType(ADD)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isOfType([ADD, REMOVE])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isOfType(ADD, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isOfType([ADD, REMOVE], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Type-Helpers API\nBelow helper functions are very flexible generalizations, works great with nested structures and will cover numerous different use-cases.\n\n#### `ActionType`\n\n_Powerful type-helper that will infer union type from **import * as ...** or **action-creator map** object._\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\n// with \"import * as ...\"\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n// TodosAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n\n// with nested action-creator map case\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    },\n  },\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `StateType`\n\n_Powerful type helper that will infer state object type from **reducer function** and **nested/combined reducers**._\n\n> **WARNING**: working with redux@4+ types\n\n```ts\nimport { combineReducers } from 'redux';\nimport { StateType } from 'typesafe-actions';\n\n// with reducer function\nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\n// with nested/combined reducers\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guides\n\n### `v3.x.x` to `v4.x.x`\nFrom `v4.x.x` all action creators will use `undefined` instead of `void` as a generic type parameter to make the action-creator function require NO parameters.\n```ts\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // <= no parameters required\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<undefined, User[], Error>();\nfetchUsersAsync.request(); // <= no parameters required\n```\n\n### `v2.x.x` to `v3.x.x`\n`v3.x.x` API is backward compatible with `v2.x.x`. You'll only need to update typescript dependency to `> v3.1`.\n\n### `v1.x.x` to `v2.x.x`\nIn v2 we provide a `createActionDeprecated` function compatible with v1 API to help with incremental migration.\n\n```ts\n// in v1 we created action-creator like this:\nconst getTodo = createAction('GET_TODO',\n  (id: string, meta: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: meta,\n  })\n);\n\ngetTodo('some_id', 'some_meta'); // { type: 'GET_TODO', payload: 'some_id', meta: 'some_meta' }\n\n// in v2 API we offer few different styles - please choose your preference\nconst getTodoNoHelpers = (id: string, meta: string) => action('GET_TODO', id, meta);\n\nconst getTodoWithHelpers = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\n\nconst getTodoFSA = createStandardAction('GET_TODO')<string, string>();\n\nconst getTodoCustom = createStandardAction('GET_TODO').map(\n  ({ id, meta }: { id: string; meta: string; }) => ({\n    payload: id,\n    meta,\n  })\n);\n```\n\n### Migrating from `redux-actions` to `typesafe-actions`\n\n- createAction(s)\n\n```ts\ncreateAction(type, payloadCreator, metaCreator) => createStandardAction(type)() || createStandardAction(type).map(payloadMetaCreator)\n\ncreateActions() => // COMING SOON!\n```\n\n- handleAction(s)\n\n```ts\nhandleAction(type, reducer, initialState) => createReducer(initialState).handleAction(type, reducer)\n\nhandleActions(reducerMap, initialState) => createReducer(initialState, reducerMap)\n```\n\n> TIP: If migrating from JS -> TS, you can swap out action-creators from `redux-actions` with action-creators from `typesafe-actions` in your `handleActions` handlers. This works because the action-creators from `typesafe-actions` provide the same `toString` method implementation used by `redux-actions` to match actions to the correct reducer.\n\n- combineActions\n\nNot needed because each function in the API accept single value or array of values for action types or action creators.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Recipes\n\n### Restrict Meta type in `action` creator\nUsing this recipe you can create an action creator with restricted Meta type with exact object shape.\n\n```tsx\nexport type MetaType = {\n  analytics?: {\n    eventName: string;\n  };\n};\n\nexport const actionWithRestrictedMeta = <T extends string, P>(\n  type: T,\n  payload: P,\n  meta: MetaType\n) => action(type, payload, meta);\n\nexport const validAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { eventName: 'success' } }); // OK!\n\nexport const invalidAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { excessProp: 'no way!' } }); // Error\n// Object literal may only specify known properties, and 'excessProp' does not exist in type '{ eventName: string; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common variants of action-creators (with type only, with payload and with payload + meta)\n\nNote: tested with \"@types/redux-actions\": \"2.2.3\"\n\n**- with type only (no payload)**\n\n##### redux-actions\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible)\n\n##### typesafe-actions\n```ts\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types and no excess properties and the action \"type\" property is containing a literal type\n\n**- with payload**\n\n##### redux-actions\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` semantic argument name is changed to some generic `t1`, `type` property is widened once again and `payload` is nullable because of broken inference\n\n##### typesafe-actions\n```ts\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` infer very precise resulting type, notice working optional parameters and semantic argument names are preserved which is really important for great intellisense experience\n\n**- with payload and meta**\n\n##### redux-actions\n```ts\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a completely broken arguments arity with no type-safety because of `any` type with all the earlier issues\n\n##### typesafe-actions\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type, even with this advanced scenario all types are correct and provide complete type-safety and excellent developer experience \n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## MIT License\n\nCopyright (c) 2017 Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.0.0-0","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-io6pXuGp4GL3qcQkcHGhx62RTW9VvmueDwXL7+NPpksjk2qqchkMJdcLnAzqZmKWUuYdmuEz03UhACZcdzk+Fw==","shasum":"bcc1bab9900df804ac48ecfc4427ab0d25a3e65f","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.0.0-0.tgz","fileCount":26,"unpackedSize":111608,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdEPFrCRA9TVsSAnZWagAAThIP/iTxuldZNIi0rkuRDs+u\nX4su/dE5pa8ceaC5GpdUKrJdehvTMmNiPPkb3EYuxO5HYATFAwkbOPmznPrz\n8ETKQrM4jHPv4wZ6kiDxZvnjmQ1eaN5tEcQkzWIhJqH2YB5wudBWUkZfWslY\nFKuK0MKe2C3aYVj0I8GuU2yGQ6y7/vg+Z7qzjIyruHMNfBPONcxsGEyeKHQR\nMLiMTu8mldwHkJ0cSL1tfXpxqQXWl9VaTAkYS4AiryfRxg14HG7ITdweVDab\nG1HqaENIFsWipO14UgvUJmesS0xTASfPA0QMNOhJZbbJyKbo5cbVmgMT0cUJ\nWZv2BVzmt+lG/WLcus2zFG7VkENkCKtCTBlOGvk0ni5CzSesWCHce26zgyCu\nuCKiiskbPykVqCJ1aeoNUoLObzTnnm7Xb9K22FMaTsK17M4mm7wE/iR0SZyJ\nP0wTqJJ1s47qXaVibwLgwU3J3XNzfgv9Vx+dEb3fkGFnFBusKqAjatEj6+wP\n+dL564jAdqaLJjuUFLBG2OveeYVYM0gzwj5lx+SJqjIhdMkLSVVAyZ8mxYm7\nKkuMVaQVznyBXWJWD9yg8WlE0bCJt3S3KqmXnKxBlx1IzQlBhBWSGhAFS/rs\nYFD/SiMYq8Ezp3mxD1uvSMMhUXPVhyH4D4Om706a4moCYVMiBEKVaFrRpPbX\njsDV\r\n=GS8h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHyuhX3e5TZdrAbE6EcIpLbmVON4qUX0ujb5O108RcMaAiAwQOFSZIpaKWu79Z+gfg+ZhtMd2mfkGelQVV/N8GkRfA=="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.0.0-0_1561391466618_0.38083626815873184"},"_hasShrinkwrap":false},"5.0.0-1":{"name":"typesafe-actions","version":"5.0.0-1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.4.1","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.9.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.0.0","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.5.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"6298c8591c4f1a89d5802df72dde8e551f97e4af","readme":"<div align=\"center\">\n\n# typesafe-actions\n\nTypesafe utilities designed to reduce types **verbosity**\nand **complexity**  in Redux Architecture.\n\n_This library is part of the [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)_ ecosystem :book:  \n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Bundlephobia Size](https://img.shields.io/bundlephobia/minzip/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n[![Build Status](https://semaphoreci.com/api/v1/piotrekwitek/typesafe-actions/branches/master/shields_badge.svg)](https://semaphoreci.com/piotrekwitek/typesafe-actions)\n[![Dependencies Status](https://david-dm.org/piotrwitek/typesafe-actions/status.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![License](https://img.shields.io/npm/l/typesafe-actions.svg?style=flat)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/typesafe-actions)\n\n\n\n:star: _Found it useful? Want more updates?_ [**Show your support by giving a :star:**](https://github.com/piotrwitek/typesafe-actions/stargazers)\n\n:tada: _Now updated to support **TypeScript v3.5**_ :tada:\n\n<a href=\"https://www.buymeacoffee.com/zh9guxbA5\">\n  <img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me a Coffee\">\n</a>\n<a href=\"https://www.patreon.com/piotrekwitek\">\n  <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button@2x.png\" alt=\"Become a Patron\" width=\"160\">\n</a>\n\n</div>\n\n---\n\n**Features**\n\n- **minimalistic** - according to `size-snapshot` (Minified: 3.48 KB, Gzipped: 1.03 KB), check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n- **secure and optimized** - no external dependencies, bundled in 3 different formats (`cjs`, `esm` and `umd` for browser) with separate optimized bundles for dev & prod (same as `react`)\n- **focus on quality** - complete test-suite for an entire API surface containing regular runtime tests and extra type-tests to guarantee **type soundness** and to prevent regressions in the future TypeScript versions\n- **focus on performance** - integrated performance benchmarks to guarantee that the computational complexity of types are in check and there are no slow-downs when your application grow `npm run benchmark:XXX`\n\n\n**Codesandbox links**\n\n- Reference Todo-App implementation using `typesafe-actions`: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n- Starter to help reproduce bug reports: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n\n---\n\n## Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [Motivation](#motivation)\n- [Installation](#installation)\n- [Compatibility Notes](#compatibility-notes)\n- [Contributing Guide](#contributing-guide)\n- [Funding](#funding)\n- [Tutorial](#tutorial)\n  - [Constants](#constants)\n  - [Actions](#actions)\n    - [1. Basic actions](#1-basic-actions)\n    - [2. FSA compliant actions](#2-fsa-compliant-actions)\n    - [3. Custom actions (non-standard use-cases)](#3-custom-actions-non-standard-use-cases)\n  - [Action Helpers](#action-helpers)\n    - [Using action-creators instances instead of type-constants](#using-action-creators-instances-instead-of-type-constants)\n    - [Using regular type-constants](#using-regular-type-constants)\n  - [Reducers](#reducers)\n    - [Extending internal types to enable type-free syntax with `createReducer`](#extending-internal-types-to-enable-type-free-syntax-with-createreducer)\n    - [Using createReducer API with type-free syntax](#using-createreducer-api-with-type-free-syntax)\n    - [Alternative usage with regular switch reducer](#alternative-usage-with-regular-switch-reducer)\n  - [Async-Flows](#async-flows)\n    - [With `redux-observable` epics](#with-redux-observable-epics)\n    - [With `redux-saga` sagas](#with-redux-saga-sagas)\n- [API Docs](#api-docs)\n  - [Action-Creators API](#action-creators-api)\n    - [`action`](#action)\n    - [`createAction`](#createaction)\n    - [`createStandardAction`](#createstandardaction)\n    - [`createCustomAction`](#createcustomaction)\n    - [`createAsyncAction`](#createasyncaction)\n  - [Reducer-Creators API](#reducer-creators-api)\n    - [`createReducer`](#createreducer)\n  - [Action-Helpers API](#action-helpers-api)\n    - [`getType`](#gettype)\n    - [`isActionOf`](#isactionof)\n    - [`isOfType`](#isoftype)\n  - [Type-Helpers API](#type-helpers-api)\n    - [`ActionType`](#actiontype)\n    - [`StateType`](#statetype)\n- [Migration Guides](#migration-guides)\n  - [`v3.x.x` to `v4.x.x`](#v3xx-to-v4xx)\n  - [`v2.x.x` to `v3.x.x`](#v2xx-to-v3xx)\n  - [`v1.x.x` to `v2.x.x`](#v1xx-to-v2xx)\n  - [Migrating from `redux-actions` to `typesafe-actions`](#migrating-from-redux-actions-to-typesafe-actions)\n- [Recipes](#recipes)\n  - [Restrict Meta type in `action` creator](#restrict-meta-type-in-action-creator)\n- [Compare to others](#compare-to-others)\n  - [`redux-actions`](#redux-actions)\n- [MIT License](#mit-license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n--- \n\n## Motivation\n\nWhen I started to combine Redux with TypeScript, I was trying to use [redux-actions](https://redux-actions.js.org/) to reduce the maintainability cost and boilerplate of **action-creators**. Unfortunately, the results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here for a detailed comparison)](#redux-actions).\n\nExisting solutions in the wild have been either **too verbose because of redundant type annotations** (hard to maintain) or **used classes** (hinders readability and requires using the **new** keyword 😱)\n\n**So I created `typesafe-actions` to address all of the above pain points.**\n\nThe core idea was to design an API that would mostly use the power of TypeScript **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition, I wanted to make it \"look and feel\" as close as possible to the idiomatic JavaScript ❤️ , so we don't have to write the redundant type annotations that which will create additional noise in your code.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compatibility Notes\n\n**TypeScript support**\n\n- `typesafe-actions@1.X.X` - minimal TS v2.7\n- `typesafe-actions@2.X.X` - minimal TS v2.9\n- `typesafe-actions@3.X.X` - minimal TS v3.2\n- `typesafe-actions@4.X.X` - minimal TS v3.2\n\n**Browser support**\n\nIt's compatible with all modern browsers.\n\nFor older browsers support (e.g. IE <= 11) and some mobile devices you need to provide the following polyfills:\n- [Object.assign](https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Object/assign#Polyfill)\n- [Array.prototype.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)\n\n**Recommended polyfill for IE**\n\nTo provide the best compatibility please include a popular polyfill package in your application, such as `core-js` or `react-app-polyfill` for `create-react-app`.\nPlease check the `React` guidelines to learn how to do that: [LINK](https://reactjs.org/docs/javascript-environment-requirements.html)\nA polyfill fo IE11 is included in our `/codesandbox` application.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Contributing Guide\n\nWe are open for contributions. If you're planning to contribute please make sure to read the contributing guide: [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Funding\n**Typesafe-Actions** is an independent open-source project created by people investing their free time for the benefit of our community.\n\nIf you are using **Typesafe-Actions** please consider donating as this will guarantee the project will be updated and maintained in the long run.\n\nIssues can be funded by anyone interested in them being resolved. Reward will be transparently distributed to the contributor handling the task through the IssueHunt platform.\n\n[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/110746954)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the flexibility and the power of the **type-safety** provided by this library, let's build the most common parts of a typical todo-app using a Redux architecture:\n\n> **WARNING**  \n> Please make sure that you are familiar with the following concepts of programming languages to be able to follow along: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n[⇧ back to top](#table-of-contents)\n\n### Constants\n\n> **RECOMMENDATION:**  \n> When using `typesafe-actions` in your project you won't need to export and reuse **string constants**. It's because **action-creators** created by this library have static property with **action type** that you can easily access using **actions-helpers** and then use it in reducers, epics, sagas, and basically any other place. This will simplify your codebase and remove some boilerplate code associated with the usage of **string constants**. Check our `/codesandbox` application to learn some best-practices to create such codebase.\n\n**Limitations of TypeScript when working with string constants** - when using **string constants** as action `type` property, please make sure to use **simple string literal assignment with const**. This limitation is coming from the type-system, because all the **dynamic string operations** (e.g. string concatenation, template strings and also object used as a map) will widen the literal type to its super-type, `string`. As a result this will break contextual typing for **action** object in reducer cases.\n\n```ts\n// Example file: './constants.ts'\n\n// WARNING: Incorrect usage\nexport const ADD = prefix + 'ADD'; // => string\nexport const ADD = `${prefix}/ADD`; // => string\nexport default {\n   ADD: '@prefix/ADD', // => string\n}\n\n// Correct usage\nexport const ADD = '@prefix/ADD'; // => '@prefix/ADD'\nexport const TOGGLE = '@prefix/TOGGLE'; // => '@prefix/TOGGLE'\nexport default ({\n  ADD: '@prefix/ADD', // => '@prefix/ADD'\n} as const) // working in TS v3.4 and above => https://github.com/Microsoft/TypeScript/pull/29510\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Actions\n\nDifferent projects have different needs, and conventions vary across teams, and this is why `typesafe-actions` was designed with flexibility in mind. It provides three different major styles so you can choose whichever would be the best fit for your team.\n\n#### 1. Basic actions\n`action` and `createAction` are creators that can create **actions** with predefined properties ({ type, payload, meta }). This make them concise but also opinionated.\n \nImportant property is that resulting **action-creator** will have a variadic number of arguments and preserve their semantic names `(id, title, amount, etc...)`.\n\nThis two creators are very similar and the only real difference is that `action` **WILL NOT WORK** with **action-helpers**.\n\n```ts\nimport { action, createAction } from 'typesafe-actions';\n\nexport const add = (title: string) => action('todos/ADD', { id: cuid(), title, completed: false });\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n\nexport const add = createAction('todos/ADD', action => {\n  // Note: \"action\" callback does not need \"type\" parameter\n  return (title: string) => action({ id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 2. FSA compliant actions\nThis style is aligned with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action), so your **action** object shape is constrained to `({ type, payload, meta, error })`. It is using **generic type arguments** for `meta` and `payload` to simplify creation of type-safe action-creators.\n\nIt is important to notice that in the resulting **action-creator** arguments are also constrained to the predefined: `(payload, meta)`, making it the most opinionated creator.\n\n> **TIP**: This creator is the most compatible with `redux-actions` in case you are migrating.\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// toggle: (payload: string) => { type: \"todos/TOGGLE\"; payload: string; }\n\nexport const add = createStandardAction('todos/ADD').map(\n  (title: string) => ({\n    payload: { id: cuid(), title, completed: false },\n  })\n);\n// add: (payload: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 3. Custom actions (non-standard use-cases)\n\nThis approach will give us the most flexibility of all creators, providing a variadic number of named parameters and custom properties on **action** object to fit all the custom use-cases.\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('todos/ADD', type => {\n  return (title: string) => ({ type, id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; id: string; title: string; completed: boolean; }\n```\n\n> **TIP**: For more examples please check the [API Docs](#table-of-contents).\n\n> **RECOMMENDATION**  \n> Common approach is to create a `RootAction` in the central point of your redux store - it will represent all possible action types in your application. You can even merge it with third-party action types as shown below to make your model complete.\n\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\nimport { TodosAction } from '../features/todos';\n\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Action Helpers\n\nNow I want to show you **action-helpers** and explain their use-cases. We're going to implement a side-effect responsible for showing a success toast when user adds a new todo.\n\nImportant thing to notice is that all these helpers are acting as a **type-guard** so they'll narrow **tagged union type** (`RootAction`) to a specific action type that we want.\n\n#### Using action-creators instances instead of type-constants\n\nInstead of **type-constants** we can use **action-creators** instance to match specific actions in reducers and epics cases. It works by adding a static property on **action-creator** instance which contains the `type` string. \n\nThe most common one is `getType`, which is useful for regular reducer switch cases:\n\n```ts\n  switch (action.type) {\n    case getType(todos.add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\nThen we have the `isActionOf` helper which accept **action-creator** as first parameter matching actions with corresponding type passed as second parameter (it's a curried function).\n\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      toastService.success(...);\n    })\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n#### Using regular type-constants\nAlternatively if your team prefers to use regular **type-constants** you can still do that.\n\nWe have an equivalent helper (`isOfType`) which accept **type-constants** as parameter providing the same functionality.\n\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isOfType(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isOfType([ADD, TOGGLE])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n> **TIP:** you can use action-helpers with other types of conditional statements.\n\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Reducers\n\n#### Extending internal types to enable type-free syntax with `createReducer`\n\nWe can extend internal types of `typesafe-actions` module with `RootAction` definition of our application so that you don't need to pass generic type arguments with `createReducer` API:\n\n```ts\n// types.d.ts\nimport { StateType, ActionType } from 'typesafe-actions';\n\nexport type RootAction = ActionType<typeof import('./actions').default>;\n\ndeclare module 'typesafe-actions' {\n  interface Types {\n    RootAction: RootAction;\n  }\n}\n\n// now you can use\ncreateReducer(...)\n// instead of\ncreateReducer<State, Action>(...)\n```\n\n#### Using createReducer API with type-free syntax\n\nWe can prevent a lot of boilerplate code and type errors using this powerfull and completely typesafe API.\n\nUsing handleAction chain API:\n```ts\n// using action-creators\nconst counterReducer = createReducer(0)\n  // state and action type is automatically inferred and return type is validated to be exact type\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(add, ... // <= error is shown on duplicated or invalid actions\n  .handleAction(increment, (state, _) => state + 1)\n  .handleAction(... // <= error is shown when all actions are handled\n  \n  // or handle multiple actions using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer(0)\n  .handleAction('ADD', (state, action) => state + action.payload)\n  .handleAction('INCREMENT', (state, _) => state + 1);\n  \ncounterReducer(0, add(4)); // => 4\ncounterReducer(0, increment()); // => 1\n```\n\n#### Alternative usage with regular switch reducer\n\nFirst we need to start by generating a **tagged union type** of actions (`TodosAction`). It's very easy to do by using `ActionType` **type-helper**.\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\n\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (`TodosAction` for action type).\n\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\n\nNow in the switch cases we can use the `type` property of action to narrowing the union type of `TodosAction` to an action that is corresponding to that type.\n\n```ts\n  switch (action.type) {\n    case getType(add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Async-Flows\n\n#### With `redux-observable` epics\n\nTo handle an async-flow of http request lets implement an `epic`. The `epic` will call a remote API using an injected `todosApi` client, which will return a Promise that we'll need to handle by using three different actions that correspond to triggering, success and failure.\n\nTo help us simplify the creation process of necessary action-creators, we'll use `createAsyncAction` function providing us with a nice common interface object `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for **actions** and **action-creators** that would otherwise be written explicitly.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE',\n  'FETCH_TODOS_CANCEL'\n)<string, Todo[], Error, string>();\n\n// epics.ts\nimport { fetchTodosAsync } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodosAsync.request)),\n    switchMap(action =>\n      from(todosApi.getAll(action.payload)).pipe(\n        map(fetchTodosAsync.success),\n        catchError(pipe(fetchTodosAsync.failure, of)),\n        takeUntil(action$.pipe(filter(isActionOf(fetchTodosAsync.cancel)))),\n      )\n    );\n```\n\n#### With `redux-saga` sagas\nWith sagas it's not possible to achieve the same degree of type-safety as with epics because of limitations coming from `redux-saga` API design.\n\nTypescript issues:\n- [Typescript does not currently infer types resulting from a `yield` statement](https://github.com/Microsoft/TypeScript/issues/2983) so you have to manually assert the type  e.g. `const response: Todo[] = yield call(...`\n\n*Here is the latest recommendation although it's not fully optimal. If you managed to cook something better, please open an issue to share your finding with us.*\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\nfunction* addTodoSaga(action: ReturnType<typeof fetchTodosAsync.request>): Generator {\n    const response: Todo[] = yield call(todosApi.getAll, action.payload);\n\n    yield put(fetchTodosAsync.success(response));\n  } catch (err) {\n    yield put(fetchTodosAsync.failure(err));\n  }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs\n\n### Action-Creators API\n\n#### `action`\n\n_Simple **action factory function** to simplify creation of type-safe actions._\n\n> **WARNING**:  \n> This approach will **NOT WORK** with **action-helpers** (such as `getType` and `isActionOf`) because it is creating **action objects** while all the other creator functions are returning **enhanced action-creators**.\n\n```ts\naction(type, payload?, meta?, error?)\n```\n\nExamples:\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst increment = () => action('INCREMENT');\n// { type: 'INCREMENT'; }\n\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string }; }\n\nconst getUsers = (params?: string) =>\n  action('GET_USERS', undefined, params);\n// { type: 'GET_USERS'; meta: string | undefined; }\n```\n\n> **TIP**: Starting from TypeScript v3.4 you can achieve similar results using new `as const` operator.\n\n```ts\nconst increment = () => ({ type: 'INCREMENT' } as const);\n```\n\n#### `createAction`\n\n_Create an enhanced action-creator with unlimited number of arguments._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have predefined properties `({ type, payload, meta })`\n\n```ts\ncreateAction(type)\ncreateAction(type, actionCallback => {\n  return (namedArg1, namedArg2, ...namedArgN) => actionCallback(payload?, meta?)\n})\n```\n> **TIP**: Injected `actionCallback` argument is similar to `action` API but doesn't need the \"type\" parameter\n\nExamples:\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// - with type only\nconst increment = createAction('INCREMENT');\ndispatch(increment());\n// { type: 'INCREMENT' };\n\n// - with type and payload\nconst add = createAction('ADD', action => {\n  return (amount: number) => action(amount);\n});\ndispatch(add(10));\n// { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getTodos = createAction('GET_TODOS', action => {\n  return (params: Params) => action(undefined, params);\n});\ndispatch(getTodos('some_meta'));\n// { type: 'GET_TODOS', meta: Params }\n\n// - and finally with type, payload and meta\nconst getTodo = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\ndispatch(getTodo('some_id', 'some_meta'));\n// { type: 'GET_TODO', payload: string, meta: string }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createStandardAction`\n\n_Create an enhanced action-creator compatible with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action) to reduce boilerplate and enforce convention._\n- Resulting action-creator have predefined arguments `(payload, meta)`\n- Returned action object have predefined properties `({ type, payload, meta, error })`\n- But it also contains a `.map()` method that allow to map `(payload, meta)` arguments to a custom action object `({ customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateStandardAction(type)()\ncreateStandardAction(type)<TPayload, TMeta?>()\ncreateStandardAction(type).map((payload, meta) => ({ customProp1, customProp2, ...customPropN }))\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\n// Very concise with use of generic type arguments\n// - with type only\nconst increment = createStandardAction('INCREMENT')();\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // { type: 'INCREMENT' } (no parameters are required)\n\n\n// - with type and payload\nconst add = createStandardAction('ADD')<number>();\nadd(10); // { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getData = createStandardAction('GET_DATA')<undefined, string>();\ngetData(undefined, 'meta'); // { type: 'GET_DATA', meta: string }\n\n// - and finally with type, payload and meta\nconst getData = createStandardAction('GET_DATA')<number, string>();\ngetData(1, 'meta'); // { type: 'GET_DATA', payload: number, meta: string }\n\n// Can map payload and meta arguments to a custom action object\nconst notify = createStandardAction('NOTIFY').map(\n  (payload: string, meta: Meta) => ({\n    from: meta.username,\n    message: `${username}: ${payload}`,\n    messageType: meta.type,\n    datetime: new Date(),\n  })\n);\n\ndispatch(notify('Hello!', { username: 'Piotr', type: 'announcement' }));\n// { type: 'NOTIFY', from: string, message: string, messageType: MessageType, datetime: Date }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createCustomAction`\n\n_Create an enhanced action-creator with unlimited number of arguments and custom properties on action object._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have custom properties `({ type, customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateCustomAction(type, type => {\n  return (namedArg1, namedArg2, ...namedArgN) => ({ type, customProp1, customProp2, ...customPropN })\n})\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action-with-type.spec.ts)\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\ndispatch(add(1));\n// { type: \"CUSTOM\"; customProp1: number; customProp2: number; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createAsyncAction`\n\n_Create an object containing three enhanced action-creators to simplify handling of async flows (e.g. network request - request/success/failure)._\n\n```ts\ncreateAsyncAction(\n  requestType, successType, failureType, cancelType?\n)<TRequestPayload, TSuccessPayload, TFailurePayload, TCancelPayload?>()\n```\n\n##### `AsyncActionCreator`\n\n```ts\ntype AsyncActionCreator<\n  [TRequestType, TRequestPayload],\n  [TSuccessType, TSuccessPayload],\n  [TFailureType, TFailurePayload],\n  [TCancelType, TCancelPayload]?\n> = {\n  request: StandardActionCreator<TRequestType, TRequestPayload>,\n  success: StandardActionCreator<TSuccessType, TSuccessPayload>,\n  failure: StandardActionCreator<TFailureType, TFailurePayload>,\n  cancel?: StandardActionCreator<TCancelType, TCancelPayload>,\n}\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction, AsyncActionCreator } from 'typesafe-actions';\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<string, User[], Error>();\n\ndispatch(fetchUsersAsync.request(params));\n\ndispatch(fetchUsersAsync.success(response));\n\ndispatch(fetchUsersAsync.failure(err));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error]\n  >\n) => a;\nfn(fetchUsersAsync);\n\n// There is 4th optional argument to declare cancel action\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n  'FETCH_USERS_CANCEL'\n)<string, User[], Error, string>();\n\ndispatch(fetchUsersAsync.cancel('reason'));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error],\n    ['FETCH_USERS_CANCEL', string]\n  >\n) => a;\nfn(fetchUsersAsync);\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Reducer-Creators API\n\n#### `createReducer`\n\n_Create a typesafe reducer_\n\n```ts\ncreateReducer<TState, TRootAction>(initialState, handlersMap?)\n// or\ncreateReducer<TState, TRootAction>(initialState)\n  .handleAction(actionCreator, reducer)\n  .handleAction([actionCreator1, actionCreator2, ...actionCreatorN], reducer)\n  .handleType(type, reducer)\n  .handleType([type1, type2, ...typeN], reducer)\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-reducer.spec.ts)\n\n> **TIP:** You can use reducer API with a **type-free** syntax by [Extending internal types](#extending-internal-types-to-enable-type-free-syntax-with-createreducer), otherwise you'll have to pass generic type arguments like in below examples\n```ts\n// type-free syntax doesn't require generic type arguments\nconst counterReducer = createReducer(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Object map style:**\n```ts\nimport { createReducer, getType } from 'typesafe-actions'\n\ntype State = number;\ntype Action = { type: 'ADD', payload: number } | { type: 'INCREMENT' };\n\nconst counterReducer = createReducer<State, Action>(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Chain API style:**\n```ts\n// using action-creators\nconst counterReducer = createReducer<State, Action>(0)\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(increment, (state, _) => state + 1)\n\n  // handle multiple actions by using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer<State, Action>(0)\n  .handleType('ADD', (state, action) => state + action.payload)\n  .handleType('INCREMENT', (state, _) => state + 1);\n```\n\n**Extend or compose reducers - every operation is completely typesafe:**\n```ts\nconst newCounterReducer = createReducer<State, Action>(0)\n  .handleAction('SUBTRACT', (state, action) => state - action.payload)\n  .handleAction('DECREMENT', (state, _) => state - 1);\n\nconst bigReducer = createReducer<State, Action>(0, {\n  ...counterReducer.handlers, // typesafe\n  ...newCounterReducer.handlers, // typesafe\n  SUBTRACT: decrementReducer.handlers.DECREMENT, // <= error, wrong type\n})\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-Helpers API\n\n#### `getType`\n\n_Get the **type** property value (narrowed to literal type) of given enhanced action-creator._\n\n```ts\ngetType(actionCreator)\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n```ts\nimport { getType, createStandardAction } from 'typesafe-actions';\n\nconst add = createStandardAction('ADD')<number>();\n\n// In switch reducer\nswitch (action.type) {\n  case getType(add):\n    // action type is { type: \"ADD\"; payload: number; }\n    return state + action.payload;\n\n  default:\n    return state;\n}\n\n// or with conditional statements\nif (action.type === getType(add)) {\n  // action type is { type: \"ADD\"; payload: number; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isActionOf`\n\n_Check if action is an instance of given enhanced action-creator(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n\n> **WARNING**: Regular action creators and [action](#action) will not work with this helper\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator, action)\n// or as a curried function\nisActionOf(actionCreator)(action)\n// also accepts an array\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN], action)\n// with its curried equivalent\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo, removeTodo } from './todos-actions';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isActionOf(addTodo)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isActionOf([addTodo, removeTodo])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isActionOf(addTodo, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isActionOf([addTodo, removeTodo], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isOfType`\n\n_Check if action type property is equal given type-constant(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n```ts\n// can be used as a binary function\nisOfType(type, action)\n// or as curried function\nisOfType(type)(action)\n// also accepts an array\nisOfType([type1, type2, ...typeN], action)\n// with its curried equivalent\nisOfType([type1, type2, ...typeN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD, REMOVE } from './todos-types';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isOfType(ADD)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isOfType([ADD, REMOVE])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isOfType(ADD, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isOfType([ADD, REMOVE], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Type-Helpers API\nBelow helper functions are very flexible generalizations, works great with nested structures and will cover numerous different use-cases.\n\n#### `ActionType`\n\n_Powerful type-helper that will infer union type from **import * as ...** or **action-creator map** object._\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\n// with \"import * as ...\"\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n// TodosAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n\n// with nested action-creator map case\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    },\n  },\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `StateType`\n\n_Powerful type helper that will infer state object type from **reducer function** and **nested/combined reducers**._\n\n> **WARNING**: working with redux@4+ types\n\n```ts\nimport { combineReducers } from 'redux';\nimport { StateType } from 'typesafe-actions';\n\n// with reducer function\nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\n// with nested/combined reducers\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guides\n\n### `v3.x.x` to `v4.x.x`\nFrom `v4.x.x` all action creators will use `undefined` instead of `void` as a generic type parameter to make the action-creator function require NO parameters.\n```ts\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // <= no parameters required\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<undefined, User[], Error>();\nfetchUsersAsync.request(); // <= no parameters required\n```\n\n### `v2.x.x` to `v3.x.x`\n`v3.x.x` API is backward compatible with `v2.x.x`. You'll only need to update typescript dependency to `> v3.1`.\n\n### `v1.x.x` to `v2.x.x`\nIn v2 we provide a `createActionDeprecated` function compatible with v1 API to help with incremental migration.\n\n```ts\n// in v1 we created action-creator like this:\nconst getTodo = createAction('GET_TODO',\n  (id: string, meta: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: meta,\n  })\n);\n\ngetTodo('some_id', 'some_meta'); // { type: 'GET_TODO', payload: 'some_id', meta: 'some_meta' }\n\n// in v2 API we offer few different styles - please choose your preference\nconst getTodoNoHelpers = (id: string, meta: string) => action('GET_TODO', id, meta);\n\nconst getTodoWithHelpers = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\n\nconst getTodoFSA = createStandardAction('GET_TODO')<string, string>();\n\nconst getTodoCustom = createStandardAction('GET_TODO').map(\n  ({ id, meta }: { id: string; meta: string; }) => ({\n    payload: id,\n    meta,\n  })\n);\n```\n\n### Migrating from `redux-actions` to `typesafe-actions`\n\n- createAction(s)\n\n```ts\ncreateAction(type, payloadCreator, metaCreator) => createStandardAction(type)() || createStandardAction(type).map(payloadMetaCreator)\n\ncreateActions() => // COMING SOON!\n```\n\n- handleAction(s)\n\n```ts\nhandleAction(type, reducer, initialState) => createReducer(initialState).handleAction(type, reducer)\n\nhandleActions(reducerMap, initialState) => createReducer(initialState, reducerMap)\n```\n\n> TIP: If migrating from JS -> TS, you can swap out action-creators from `redux-actions` with action-creators from `typesafe-actions` in your `handleActions` handlers. This works because the action-creators from `typesafe-actions` provide the same `toString` method implementation used by `redux-actions` to match actions to the correct reducer.\n\n- combineActions\n\nNot needed because each function in the API accept single value or array of values for action types or action creators.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Recipes\n\n### Restrict Meta type in `action` creator\nUsing this recipe you can create an action creator with restricted Meta type with exact object shape.\n\n```tsx\nexport type MetaType = {\n  analytics?: {\n    eventName: string;\n  };\n};\n\nexport const actionWithRestrictedMeta = <T extends string, P>(\n  type: T,\n  payload: P,\n  meta: MetaType\n) => action(type, payload, meta);\n\nexport const validAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { eventName: 'success' } }); // OK!\n\nexport const invalidAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { excessProp: 'no way!' } }); // Error\n// Object literal may only specify known properties, and 'excessProp' does not exist in type '{ eventName: string; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common variants of action-creators (with type only, with payload and with payload + meta)\n\nNote: tested with \"@types/redux-actions\": \"2.2.3\"\n\n**- with type only (no payload)**\n\n##### redux-actions\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible)\n\n##### typesafe-actions\n```ts\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types and no excess properties and the action \"type\" property is containing a literal type\n\n**- with payload**\n\n##### redux-actions\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` semantic argument name is changed to some generic `t1`, `type` property is widened once again and `payload` is nullable because of broken inference\n\n##### typesafe-actions\n```ts\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` infer very precise resulting type, notice working optional parameters and semantic argument names are preserved which is really important for great intellisense experience\n\n**- with payload and meta**\n\n##### redux-actions\n```ts\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a completely broken arguments arity with no type-safety because of `any` type with all the earlier issues\n\n##### typesafe-actions\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type, even with this advanced scenario all types are correct and provide complete type-safety and excellent developer experience \n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## MIT License\n\nCopyright (c) 2017 Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.0.0-1","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-GY0dk7cF6gaNl2KpXMowWmXWzOkZh/w+WplrCwe4V6+ZvtGs+1LKcZJ3GEv4YVR5v1DgPDPOR1XlU1JKYwI2vw==","shasum":"bf1c7161c336fd9a256db3d979eb724d91ba7947","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.0.0-1.tgz","fileCount":26,"unpackedSize":111841,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdFfg/CRA9TVsSAnZWagAAjOAQAJQZPgkBNSL5LoqHyQjA\nY1GLGkH+7uWy2gz14LHvQhAp8OqZ2MaeVFe8v3faunABHY/IH5Pzcg5LVgXp\nbks/b2+q1/GX3sMYfuz9YmqFO8ETOQ+w24k/JSlRJv8+zWfigNLqGhQBgl2E\nKKS+GcsrMK06nBrR6c6dgyCzrI/t6zzdmZF8S0hEC3tr1EfXwNBugeran8/K\nM/axG/6jDw+FbOc9V0jtIaLPpreJUauUAzmQIhtJ/y9aKsr9rl+AzTPAoOrw\nSS8HrFlIkOU5Zl0ndBXt6gJqq0VM9dOoWKkIuy2VqKwOoNtSLH6OJQABKKGV\ni061tFoLc5roSRsUKWk2RFe57UcR6cEM3DtL3aXU3Bq7dsdeIR0RSIcXQjy9\nXrKASMjH8qo0MNwNUT2soFeDJ1Eagi1pm+e2s1BnbhQgKfOvMG6YrRDzdeUU\nL2djsfEsK5M1bMesu5fsBqbpaaHblzWExwP0A3BVLe6qL4aSt2HwL2PHMEKh\nH2CfaNytCApDNWl3MKI3g1krp8tsQOPNNYg0JAi6qdUh5tjxo5NgSvN/mDNz\nUh8tfB9q0wXa6zy2iTZ2ShyT9D55BRLjgZj/UoTzWr49r/AP3hpPSLmgkET8\ncOUwcIxk1h56YEh1AOLvcfRUmvx94xqlcyXTX7dtB1u6dMhajWqstaonEkH6\nl/Ux\r\n=myZx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC+Cd4IMt9sBb2xcQ4QYWB8crV71LOpMJXtomzLEdC+ZAIhAIwE5Vimk8L1gdReUcE/I4xPiuZro4HvX2oFiVX9Jl+l"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.0.0-1_1561720894932_0.7944790621664817"},"_hasShrinkwrap":false},"5.0.0-3":{"name":"typesafe-actions","version":"5.0.0-3","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p . --noEmit","tsc:watch":"tsc -p . --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p . && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"2.4.1","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.9.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.0.0","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.5.2"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"e81d8f9541d604b6529ca92b2e820411fdd67bce","readme":"<div align=\"center\">\n\n# typesafe-actions\n\nTypesafe utilities designed to reduce types **verbosity**\nand **complexity**  in Redux Architecture.\n\n_This library is part of the [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)_ ecosystem :book:  \n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Bundlephobia Size](https://img.shields.io/bundlephobia/minzip/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n[![Build Status](https://semaphoreci.com/api/v1/piotrekwitek/typesafe-actions/branches/master/shields_badge.svg)](https://semaphoreci.com/piotrekwitek/typesafe-actions)\n[![Dependencies Status](https://david-dm.org/piotrwitek/typesafe-actions/status.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![License](https://img.shields.io/npm/l/typesafe-actions.svg?style=flat)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/typesafe-actions)\n\n\n\n:star: _Found it useful? Want more updates?_ [**Show your support by giving a :star:**](https://github.com/piotrwitek/typesafe-actions/stargazers)\n\n:tada: _Now updated to support **TypeScript v3.5**_ :tada:\n\n<a href=\"https://www.buymeacoffee.com/zh9guxbA5\">\n  <img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me a Coffee\">\n</a>\n<a href=\"https://www.patreon.com/piotrekwitek\">\n  <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button@2x.png\" alt=\"Become a Patron\" width=\"160\">\n</a>\n\n</div>\n\n---\n\n**Features**\n\n- **minimalistic** - according to `size-snapshot` (Minified: 3.48 KB, Gzipped: 1.03 KB), check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n- **secure and optimized** - no external dependencies, bundled in 3 different formats (`cjs`, `esm` and `umd` for browser) with separate optimized bundles for dev & prod (same as `react`)\n- **focus on quality** - complete test-suite for an entire API surface containing regular runtime tests and extra type-tests to guarantee **type soundness** and to prevent regressions in the future TypeScript versions\n- **focus on performance** - integrated performance benchmarks to guarantee that the computational complexity of types are in check and there are no slow-downs when your application grow `npm run benchmark:XXX`\n\n\n**Codesandbox links**\n\n- Reference Todo-App implementation using `typesafe-actions`: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n- Starter to help reproduce bug reports: [Link](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n\n---\n\n## Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [Motivation](#motivation)\n- [Installation](#installation)\n- [Compatibility Notes](#compatibility-notes)\n- [Contributing Guide](#contributing-guide)\n- [Funding](#funding)\n- [Tutorial](#tutorial)\n  - [Constants](#constants)\n  - [Actions](#actions)\n    - [1. Basic actions](#1-basic-actions)\n    - [2. FSA compliant actions](#2-fsa-compliant-actions)\n    - [3. Custom actions (non-standard use-cases)](#3-custom-actions-non-standard-use-cases)\n  - [Action Helpers](#action-helpers)\n    - [Using action-creators instances instead of type-constants](#using-action-creators-instances-instead-of-type-constants)\n    - [Using regular type-constants](#using-regular-type-constants)\n  - [Reducers](#reducers)\n    - [Extending internal types to enable type-free syntax with `createReducer`](#extending-internal-types-to-enable-type-free-syntax-with-createreducer)\n    - [Using createReducer API with type-free syntax](#using-createreducer-api-with-type-free-syntax)\n    - [Alternative usage with regular switch reducer](#alternative-usage-with-regular-switch-reducer)\n  - [Async-Flows](#async-flows)\n    - [With `redux-observable` epics](#with-redux-observable-epics)\n    - [With `redux-saga` sagas](#with-redux-saga-sagas)\n- [API Docs](#api-docs)\n  - [Action-Creators API](#action-creators-api)\n    - [`action`](#action)\n    - [`createAction`](#createaction)\n    - [`createStandardAction`](#createstandardaction)\n    - [`createCustomAction`](#createcustomaction)\n    - [`createAsyncAction`](#createasyncaction)\n  - [Reducer-Creators API](#reducer-creators-api)\n    - [`createReducer`](#createreducer)\n  - [Action-Helpers API](#action-helpers-api)\n    - [`getType`](#gettype)\n    - [`isActionOf`](#isactionof)\n    - [`isOfType`](#isoftype)\n  - [Type-Helpers API](#type-helpers-api)\n    - [`ActionType`](#actiontype)\n    - [`StateType`](#statetype)\n- [Migration Guides](#migration-guides)\n  - [`v3.x.x` to `v4.x.x`](#v3xx-to-v4xx)\n  - [`v2.x.x` to `v3.x.x`](#v2xx-to-v3xx)\n  - [`v1.x.x` to `v2.x.x`](#v1xx-to-v2xx)\n  - [Migrating from `redux-actions` to `typesafe-actions`](#migrating-from-redux-actions-to-typesafe-actions)\n- [Recipes](#recipes)\n  - [Restrict Meta type in `action` creator](#restrict-meta-type-in-action-creator)\n- [Compare to others](#compare-to-others)\n  - [`redux-actions`](#redux-actions)\n- [MIT License](#mit-license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n--- \n\n## Motivation\n\nWhen I started to combine Redux with TypeScript, I was trying to use [redux-actions](https://redux-actions.js.org/) to reduce the maintainability cost and boilerplate of **action-creators**. Unfortunately, the results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here for a detailed comparison)](#redux-actions).\n\nExisting solutions in the wild have been either **too verbose because of redundant type annotations** (hard to maintain) or **used classes** (hinders readability and requires using the **new** keyword 😱)\n\n**So I created `typesafe-actions` to address all of the above pain points.**\n\nThe core idea was to design an API that would mostly use the power of TypeScript **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition, I wanted to make it \"look and feel\" as close as possible to the idiomatic JavaScript ❤️ , so we don't have to write the redundant type annotations that which will create additional noise in your code.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Installation\n\n```bash\n// NPM\nnpm install typesafe-actions\n\n// YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compatibility Notes\n\n**TypeScript support**\n\n- `typesafe-actions@1.X.X` - minimal TS v2.7\n- `typesafe-actions@2.X.X` - minimal TS v2.9\n- `typesafe-actions@3.X.X` - minimal TS v3.2\n- `typesafe-actions@4.X.X` - minimal TS v3.2\n\n**Browser support**\n\nIt's compatible with all modern browsers.\n\nFor older browsers support (e.g. IE <= 11) and some mobile devices you need to provide the following polyfills:\n- [Object.assign](https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Object/assign#Polyfill)\n- [Array.prototype.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)\n\n**Recommended polyfill for IE**\n\nTo provide the best compatibility please include a popular polyfill package in your application, such as `core-js` or `react-app-polyfill` for `create-react-app`.\nPlease check the `React` guidelines to learn how to do that: [LINK](https://reactjs.org/docs/javascript-environment-requirements.html)\nA polyfill fo IE11 is included in our `/codesandbox` application.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Contributing Guide\n\nWe are open for contributions. If you're planning to contribute please make sure to read the contributing guide: [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Funding\n**Typesafe-Actions** is an independent open-source project created by people investing their free time for the benefit of our community.\n\nIf you are using **Typesafe-Actions** please consider donating as this will guarantee the project will be updated and maintained in the long run.\n\nIssues can be funded by anyone interested in them being resolved. Reward will be transparently distributed to the contributor handling the task through the IssueHunt platform.\n\n[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/110746954)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial\n\nTo showcase the flexibility and the power of the **type-safety** provided by this library, let's build the most common parts of a typical todo-app using a Redux architecture:\n\n> **WARNING**  \n> Please make sure that you are familiar with the following concepts of programming languages to be able to follow along: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n[⇧ back to top](#table-of-contents)\n\n### Constants\n\n> **RECOMMENDATION:**  \n> When using `typesafe-actions` in your project you won't need to export and reuse **string constants**. It's because **action-creators** created by this library have static property with **action type** that you can easily access using **actions-helpers** and then use it in reducers, epics, sagas, and basically any other place. This will simplify your codebase and remove some boilerplate code associated with the usage of **string constants**. Check our `/codesandbox` application to learn some best-practices to create such codebase.\n\n**Limitations of TypeScript when working with string constants** - when using **string constants** as action `type` property, please make sure to use **simple string literal assignment with const**. This limitation is coming from the type-system, because all the **dynamic string operations** (e.g. string concatenation, template strings and also object used as a map) will widen the literal type to its super-type, `string`. As a result this will break contextual typing for **action** object in reducer cases.\n\n```ts\n// Example file: './constants.ts'\n\n// WARNING: Incorrect usage\nexport const ADD = prefix + 'ADD'; // => string\nexport const ADD = `${prefix}/ADD`; // => string\nexport default {\n   ADD: '@prefix/ADD', // => string\n}\n\n// Correct usage\nexport const ADD = '@prefix/ADD'; // => '@prefix/ADD'\nexport const TOGGLE = '@prefix/TOGGLE'; // => '@prefix/TOGGLE'\nexport default ({\n  ADD: '@prefix/ADD', // => '@prefix/ADD'\n} as const) // working in TS v3.4 and above => https://github.com/Microsoft/TypeScript/pull/29510\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Actions\n\nDifferent projects have different needs, and conventions vary across teams, and this is why `typesafe-actions` was designed with flexibility in mind. It provides three different major styles so you can choose whichever would be the best fit for your team.\n\n#### 1. Basic actions\n`action` and `createAction` are creators that can create **actions** with predefined properties ({ type, payload, meta }). This make them concise but also opinionated.\n \nImportant property is that resulting **action-creator** will have a variadic number of arguments and preserve their semantic names `(id, title, amount, etc...)`.\n\nThis two creators are very similar and the only real difference is that `action` **WILL NOT WORK** with **action-helpers**.\n\n```ts\nimport { action, createAction } from 'typesafe-actions';\n\nexport const add = (title: string) => action('todos/ADD', { id: cuid(), title, completed: false });\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n\nexport const add = createAction('todos/ADD', action => {\n  // Note: \"action\" callback does not need \"type\" parameter\n  return (title: string) => action({ id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 2. FSA compliant actions\nThis style is aligned with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action), so your **action** object shape is constrained to `({ type, payload, meta, error })`. It is using **generic type arguments** for `meta` and `payload` to simplify creation of type-safe action-creators.\n\nIt is important to notice that in the resulting **action-creator** arguments are also constrained to the predefined: `(payload, meta)`, making it the most opinionated creator.\n\n> **TIP**: This creator is the most compatible with `redux-actions` in case you are migrating.\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// toggle: (payload: string) => { type: \"todos/TOGGLE\"; payload: string; }\n\nexport const add = createStandardAction('todos/ADD').map(\n  (title: string) => ({\n    payload: { id: cuid(), title, completed: false },\n  })\n);\n// add: (payload: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 3. Custom actions (non-standard use-cases)\n\nThis approach will give us the most flexibility of all creators, providing a variadic number of named parameters and custom properties on **action** object to fit all the custom use-cases.\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('todos/ADD', type => {\n  return (title: string) => ({ type, id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; id: string; title: string; completed: boolean; }\n```\n\n> **TIP**: For more examples please check the [API Docs](#table-of-contents).\n\n> **RECOMMENDATION**  \n> Common approach is to create a `RootAction` in the central point of your redux store - it will represent all possible action types in your application. You can even merge it with third-party action types as shown below to make your model complete.\n\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\nimport { TodosAction } from '../features/todos';\n\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Action Helpers\n\nNow I want to show you **action-helpers** and explain their use-cases. We're going to implement a side-effect responsible for showing a success toast when user adds a new todo.\n\nImportant thing to notice is that all these helpers are acting as a **type-guard** so they'll narrow **tagged union type** (`RootAction`) to a specific action type that we want.\n\n#### Using action-creators instances instead of type-constants\n\nInstead of **type-constants** we can use **action-creators** instance to match specific actions in reducers and epics cases. It works by adding a static property on **action-creator** instance which contains the `type` string. \n\nThe most common one is `getType`, which is useful for regular reducer switch cases:\n\n```ts\n  switch (action.type) {\n    case getType(todos.add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\nThen we have the `isActionOf` helper which accept **action-creator** as first parameter matching actions with corresponding type passed as second parameter (it's a curried function).\n\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      toastService.success(...);\n    })\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n#### Using regular type-constants\nAlternatively if your team prefers to use regular **type-constants** you can still do that.\n\nWe have an equivalent helper (`isOfType`) which accept **type-constants** as parameter providing the same functionality.\n\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { toastService }) =>\n  action$.pipe(\n    filter(isOfType(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isOfType([ADD, TOGGLE])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n> **TIP:** you can use action-helpers with other types of conditional statements.\n\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Reducers\n\n#### Extending internal types to enable type-free syntax with `createReducer`\n\nWe can extend internal types of `typesafe-actions` module with `RootAction` definition of our application so that you don't need to pass generic type arguments with `createReducer` API:\n\n```ts\n// types.d.ts\nimport { StateType, ActionType } from 'typesafe-actions';\n\nexport type RootAction = ActionType<typeof import('./actions').default>;\n\ndeclare module 'typesafe-actions' {\n  interface Types {\n    RootAction: RootAction;\n  }\n}\n\n// now you can use\ncreateReducer(...)\n// instead of\ncreateReducer<State, Action>(...)\n```\n\n#### Using createReducer API with type-free syntax\n\nWe can prevent a lot of boilerplate code and type errors using this powerfull and completely typesafe API.\n\nUsing handleAction chain API:\n```ts\n// using action-creators\nconst counterReducer = createReducer(0)\n  // state and action type is automatically inferred and return type is validated to be exact type\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(add, ... // <= error is shown on duplicated or invalid actions\n  .handleAction(increment, (state, _) => state + 1)\n  .handleAction(... // <= error is shown when all actions are handled\n  \n  // or handle multiple actions using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer(0)\n  .handleAction('ADD', (state, action) => state + action.payload)\n  .handleAction('INCREMENT', (state, _) => state + 1);\n  \ncounterReducer(0, add(4)); // => 4\ncounterReducer(0, increment()); // => 1\n```\n\n#### Alternative usage with regular switch reducer\n\nFirst we need to start by generating a **tagged union type** of actions (`TodosAction`). It's very easy to do by using `ActionType` **type-helper**.\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\n\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (`TodosAction` for action type).\n\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\n\nNow in the switch cases we can use the `type` property of action to narrowing the union type of `TodosAction` to an action that is corresponding to that type.\n\n```ts\n  switch (action.type) {\n    case getType(add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Async-Flows\n\n#### With `redux-observable` epics\n\nTo handle an async-flow of http request lets implement an `epic`. The `epic` will call a remote API using an injected `todosApi` client, which will return a Promise that we'll need to handle by using three different actions that correspond to triggering, success and failure.\n\nTo help us simplify the creation process of necessary action-creators, we'll use `createAsyncAction` function providing us with a nice common interface object `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for **actions** and **action-creators** that would otherwise be written explicitly.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE',\n  'FETCH_TODOS_CANCEL'\n)<string, Todo[], Error, string>();\n\n// epics.ts\nimport { fetchTodosAsync } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootAction, RootState, Services> = (action$, store, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodosAsync.request)),\n    switchMap(action =>\n      from(todosApi.getAll(action.payload)).pipe(\n        map(fetchTodosAsync.success),\n        catchError(pipe(fetchTodosAsync.failure, of)),\n        takeUntil(action$.pipe(filter(isActionOf(fetchTodosAsync.cancel)))),\n      )\n    );\n```\n\n#### With `redux-saga` sagas\nWith sagas it's not possible to achieve the same degree of type-safety as with epics because of limitations coming from `redux-saga` API design.\n\nTypescript issues:\n- [Typescript does not currently infer types resulting from a `yield` statement](https://github.com/Microsoft/TypeScript/issues/2983) so you have to manually assert the type  e.g. `const response: Todo[] = yield call(...`\n\n*Here is the latest recommendation although it's not fully optimal. If you managed to cook something better, please open an issue to share your finding with us.*\n\n```ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\nfunction* addTodoSaga(action: ReturnType<typeof fetchTodosAsync.request>): Generator {\n    const response: Todo[] = yield call(todosApi.getAll, action.payload);\n\n    yield put(fetchTodosAsync.success(response));\n  } catch (err) {\n    yield put(fetchTodosAsync.failure(err));\n  }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs\n\n### Action-Creators API\n\n#### `action`\n\n_Simple **action factory function** to simplify creation of type-safe actions._\n\n> **WARNING**:  \n> This approach will **NOT WORK** with **action-helpers** (such as `getType` and `isActionOf`) because it is creating **action objects** while all the other creator functions are returning **enhanced action-creators**.\n\n```ts\naction(type, payload?, meta?, error?)\n```\n\nExamples:\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst increment = () => action('INCREMENT');\n// { type: 'INCREMENT'; }\n\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string }; }\n\nconst getUsers = (params?: string) =>\n  action('GET_USERS', undefined, params);\n// { type: 'GET_USERS'; meta: string | undefined; }\n```\n\n> **TIP**: Starting from TypeScript v3.4 you can achieve similar results using new `as const` operator.\n\n```ts\nconst increment = () => ({ type: 'INCREMENT' } as const);\n```\n\n#### `createAction`\n\n_Create an enhanced action-creator with unlimited number of arguments._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have predefined properties `({ type, payload, meta })`\n\n```ts\ncreateAction(type)\ncreateAction(type, actionCallback => {\n  return (namedArg1, namedArg2, ...namedArgN) => actionCallback(payload?, meta?)\n})\n```\n> **TIP**: Injected `actionCallback` argument is similar to `action` API but doesn't need the \"type\" parameter\n\nExamples:\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// - with type only\nconst increment = createAction('INCREMENT');\ndispatch(increment());\n// { type: 'INCREMENT' };\n\n// - with type and payload\nconst add = createAction('ADD', action => {\n  return (amount: number) => action(amount);\n});\ndispatch(add(10));\n// { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getTodos = createAction('GET_TODOS', action => {\n  return (params: Params) => action(undefined, params);\n});\ndispatch(getTodos('some_meta'));\n// { type: 'GET_TODOS', meta: Params }\n\n// - and finally with type, payload and meta\nconst getTodo = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\ndispatch(getTodo('some_id', 'some_meta'));\n// { type: 'GET_TODO', payload: string, meta: string }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createStandardAction`\n\n_Create an enhanced action-creator compatible with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action) to reduce boilerplate and enforce convention._\n- Resulting action-creator have predefined arguments `(payload, meta)`\n- Returned action object have predefined properties `({ type, payload, meta, error })`\n- But it also contains a `.map()` method that allow to map `(payload, meta)` arguments to a custom action object `({ customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateStandardAction(type)()\ncreateStandardAction(type)<TPayload, TMeta?>()\ncreateStandardAction(type).map((payload, meta) => ({ customProp1, customProp2, ...customPropN }))\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\n// Very concise with use of generic type arguments\n// - with type only\nconst increment = createStandardAction('INCREMENT')();\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // { type: 'INCREMENT' } (no parameters are required)\n\n\n// - with type and payload\nconst add = createStandardAction('ADD')<number>();\nadd(10); // { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getData = createStandardAction('GET_DATA')<undefined, string>();\ngetData(undefined, 'meta'); // { type: 'GET_DATA', meta: string }\n\n// - and finally with type, payload and meta\nconst getData = createStandardAction('GET_DATA')<number, string>();\ngetData(1, 'meta'); // { type: 'GET_DATA', payload: number, meta: string }\n\n// Can map payload and meta arguments to a custom action object\nconst notify = createStandardAction('NOTIFY').map(\n  (payload: string, meta: Meta) => ({\n    from: meta.username,\n    message: `${username}: ${payload}`,\n    messageType: meta.type,\n    datetime: new Date(),\n  })\n);\n\ndispatch(notify('Hello!', { username: 'Piotr', type: 'announcement' }));\n// { type: 'NOTIFY', from: string, message: string, messageType: MessageType, datetime: Date }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createCustomAction`\n\n_Create an enhanced action-creator with unlimited number of arguments and custom properties on action object._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have custom properties `({ type, customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateCustomAction(type, type => {\n  return (namedArg1, namedArg2, ...namedArgN) => ({ type, customProp1, customProp2, ...customPropN })\n})\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action-with-type.spec.ts)\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\ndispatch(add(1));\n// { type: \"CUSTOM\"; customProp1: number; customProp2: number; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createAsyncAction`\n\n_Create an object containing three enhanced action-creators to simplify handling of async flows (e.g. network request - request/success/failure)._\n\n```ts\ncreateAsyncAction(\n  requestType, successType, failureType, cancelType?\n)<TRequestPayload, TSuccessPayload, TFailurePayload, TCancelPayload?>()\n```\n\n##### `AsyncActionCreator`\n\n```ts\ntype AsyncActionCreator<\n  [TRequestType, TRequestPayload],\n  [TSuccessType, TSuccessPayload],\n  [TFailureType, TFailurePayload],\n  [TCancelType, TCancelPayload]?\n> = {\n  request: StandardActionCreator<TRequestType, TRequestPayload>,\n  success: StandardActionCreator<TSuccessType, TSuccessPayload>,\n  failure: StandardActionCreator<TFailureType, TFailurePayload>,\n  cancel?: StandardActionCreator<TCancelType, TCancelPayload>,\n}\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction, AsyncActionCreator } from 'typesafe-actions';\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<string, User[], Error>();\n\ndispatch(fetchUsersAsync.request(params));\n\ndispatch(fetchUsersAsync.success(response));\n\ndispatch(fetchUsersAsync.failure(err));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error]\n  >\n) => a;\nfn(fetchUsersAsync);\n\n// There is 4th optional argument to declare cancel action\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n  'FETCH_USERS_CANCEL'\n)<string, User[], Error, string>();\n\ndispatch(fetchUsersAsync.cancel('reason'));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error],\n    ['FETCH_USERS_CANCEL', string]\n  >\n) => a;\nfn(fetchUsersAsync);\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Reducer-Creators API\n\n#### `createReducer`\n\n_Create a typesafe reducer_\n\n```ts\ncreateReducer<TState, TRootAction>(initialState, handlersMap?)\n// or\ncreateReducer<TState, TRootAction>(initialState)\n  .handleAction(actionCreator, reducer)\n  .handleAction([actionCreator1, actionCreator2, ...actionCreatorN], reducer)\n  .handleType(type, reducer)\n  .handleType([type1, type2, ...typeN], reducer)\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-reducer.spec.ts)\n\n> **TIP:** You can use reducer API with a **type-free** syntax by [Extending internal types](#extending-internal-types-to-enable-type-free-syntax-with-createreducer), otherwise you'll have to pass generic type arguments like in below examples\n```ts\n// type-free syntax doesn't require generic type arguments\nconst counterReducer = createReducer(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Object map style:**\n```ts\nimport { createReducer, getType } from 'typesafe-actions'\n\ntype State = number;\ntype Action = { type: 'ADD', payload: number } | { type: 'INCREMENT' };\n\nconst counterReducer = createReducer<State, Action>(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Chain API style:**\n```ts\n// using action-creators\nconst counterReducer = createReducer<State, Action>(0)\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(increment, (state, _) => state + 1)\n\n  // handle multiple actions by using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer<State, Action>(0)\n  .handleType('ADD', (state, action) => state + action.payload)\n  .handleType('INCREMENT', (state, _) => state + 1);\n```\n\n**Extend or compose reducers - every operation is completely typesafe:**\n```ts\nconst newCounterReducer = createReducer<State, Action>(0)\n  .handleAction('SUBTRACT', (state, action) => state - action.payload)\n  .handleAction('DECREMENT', (state, _) => state - 1);\n\nconst bigReducer = createReducer<State, Action>(0, {\n  ...counterReducer.handlers, // typesafe\n  ...newCounterReducer.handlers, // typesafe\n  SUBTRACT: decrementReducer.handlers.DECREMENT, // <= error, wrong type\n})\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-Helpers API\n\n#### `getType`\n\n_Get the **type** property value (narrowed to literal type) of given enhanced action-creator._\n\n```ts\ngetType(actionCreator)\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n```ts\nimport { getType, createStandardAction } from 'typesafe-actions';\n\nconst add = createStandardAction('ADD')<number>();\n\n// In switch reducer\nswitch (action.type) {\n  case getType(add):\n    // action type is { type: \"ADD\"; payload: number; }\n    return state + action.payload;\n\n  default:\n    return state;\n}\n\n// or with conditional statements\nif (action.type === getType(add)) {\n  // action type is { type: \"ADD\"; payload: number; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isActionOf`\n\n_Check if action is an instance of given enhanced action-creator(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n\n> **WARNING**: Regular action creators and [action](#action) will not work with this helper\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator, action)\n// or as a curried function\nisActionOf(actionCreator)(action)\n// also accepts an array\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN], action)\n// with its curried equivalent\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo, removeTodo } from './todos-actions';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isActionOf(addTodo)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isActionOf([addTodo, removeTodo])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isActionOf(addTodo, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isActionOf([addTodo, removeTodo], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isOfType`\n\n_Check if action type property is equal given type-constant(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n```ts\n// can be used as a binary function\nisOfType(type, action)\n// or as curried function\nisOfType(type)(action)\n// also accepts an array\nisOfType([type1, type2, ...typeN], action)\n// with its curried equivalent\nisOfType([type1, type2, ...typeN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD, REMOVE } from './todos-types';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isOfType(ADD)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isOfType([ADD, REMOVE])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isOfType(ADD, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isOfType([ADD, REMOVE], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Type-Helpers API\nBelow helper functions are very flexible generalizations, works great with nested structures and will cover numerous different use-cases.\n\n#### `ActionType`\n\n_Powerful type-helper that will infer union type from **import * as ...** or **action-creator map** object._\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\n// with \"import * as ...\"\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n// TodosAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n\n// with nested action-creator map case\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    },\n  },\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `StateType`\n\n_Powerful type helper that will infer state object type from **reducer function** and **nested/combined reducers**._\n\n> **WARNING**: working with redux@4+ types\n\n```ts\nimport { combineReducers } from 'redux';\nimport { StateType } from 'typesafe-actions';\n\n// with reducer function\nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\n// with nested/combined reducers\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guides\n\n### `v3.x.x` to `v4.x.x`\nFrom `v4.x.x` all action creators will use `undefined` instead of `void` as a generic type parameter to make the action-creator function require NO parameters.\n```ts\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // <= no parameters required\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<undefined, User[], Error>();\nfetchUsersAsync.request(); // <= no parameters required\n```\n\n### `v2.x.x` to `v3.x.x`\n`v3.x.x` API is backward compatible with `v2.x.x`. You'll only need to update typescript dependency to `> v3.1`.\n\n### `v1.x.x` to `v2.x.x`\nIn v2 we provide a `createActionDeprecated` function compatible with v1 API to help with incremental migration.\n\n```ts\n// in v1 we created action-creator like this:\nconst getTodo = createAction('GET_TODO',\n  (id: string, meta: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: meta,\n  })\n);\n\ngetTodo('some_id', 'some_meta'); // { type: 'GET_TODO', payload: 'some_id', meta: 'some_meta' }\n\n// in v2 API we offer few different styles - please choose your preference\nconst getTodoNoHelpers = (id: string, meta: string) => action('GET_TODO', id, meta);\n\nconst getTodoWithHelpers = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\n\nconst getTodoFSA = createStandardAction('GET_TODO')<string, string>();\n\nconst getTodoCustom = createStandardAction('GET_TODO').map(\n  ({ id, meta }: { id: string; meta: string; }) => ({\n    payload: id,\n    meta,\n  })\n);\n```\n\n### Migrating from `redux-actions` to `typesafe-actions`\n\n- createAction(s)\n\n```ts\ncreateAction(type, payloadCreator, metaCreator) => createStandardAction(type)() || createStandardAction(type).map(payloadMetaCreator)\n\ncreateActions() => // COMING SOON!\n```\n\n- handleAction(s)\n\n```ts\nhandleAction(type, reducer, initialState) => createReducer(initialState).handleAction(type, reducer)\n\nhandleActions(reducerMap, initialState) => createReducer(initialState, reducerMap)\n```\n\n> TIP: If migrating from JS -> TS, you can swap out action-creators from `redux-actions` with action-creators from `typesafe-actions` in your `handleActions` handlers. This works because the action-creators from `typesafe-actions` provide the same `toString` method implementation used by `redux-actions` to match actions to the correct reducer.\n\n- combineActions\n\nNot needed because each function in the API accept single value or array of values for action types or action creators.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Recipes\n\n### Restrict Meta type in `action` creator\nUsing this recipe you can create an action creator with restricted Meta type with exact object shape.\n\n```tsx\nexport type MetaType = {\n  analytics?: {\n    eventName: string;\n  };\n};\n\nexport const actionWithRestrictedMeta = <T extends string, P>(\n  type: T,\n  payload: P,\n  meta: MetaType\n) => action(type, payload, meta);\n\nexport const validAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { eventName: 'success' } }); // OK!\n\nexport const invalidAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { excessProp: 'no way!' } }); // Error\n// Object literal may only specify known properties, and 'excessProp' does not exist in type '{ eventName: string; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common variants of action-creators (with type only, with payload and with payload + meta)\n\nNote: tested with \"@types/redux-actions\": \"2.2.3\"\n\n**- with type only (no payload)**\n\n##### redux-actions\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible)\n\n##### typesafe-actions\n```ts\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types and no excess properties and the action \"type\" property is containing a literal type\n\n**- with payload**\n\n##### redux-actions\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` semantic argument name is changed to some generic `t1`, `type` property is widened once again and `payload` is nullable because of broken inference\n\n##### typesafe-actions\n```ts\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` infer very precise resulting type, notice working optional parameters and semantic argument names are preserved which is really important for great intellisense experience\n\n**- with payload and meta**\n\n##### redux-actions\n```ts\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a completely broken arguments arity with no type-safety because of `any` type with all the earlier issues\n\n##### typesafe-actions\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type, even with this advanced scenario all types are correct and provide complete type-safety and excellent developer experience \n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## MIT License\n\nCopyright (c) 2017 Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.0.0-3","_nodeVersion":"10.7.0","_npmVersion":"6.8.0","dist":{"integrity":"sha512-sX5Sh2FLctpj+u6HDlqiH7o/MLQCPHFb8vI2X7vp22F7G4V+IqSZdgq/31+3i0G1q8vm39W6uk5EMIeE/x5gCg==","shasum":"b54354700a3a2827859e9f86dd51576c8945fcd4","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.0.0-3.tgz","fileCount":26,"unpackedSize":111675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdGOm1CRA9TVsSAnZWagAAqzQP/2kuYpgOUppr5Axx2XxA\nXKFOHksCoACLAeDkyZTrqzTKaKPDPHWb5AsWR8Iw7Bbuky+Ioh1XAX8+tT4D\nIeO8quOZ2Y126Szn1ZC6JtlRRuiDMD2TmIYDlnJOWJOa6vHzfNNYghmv1gBe\noZ/OOyQn5zdRFbdzE6e163MRyZbdDh20J1WCIXAdXf5ove3bwluH7YEtK3bM\nhwSaQkz7+bHgiKhnwFtsDUQmU+wXwWxESdo+tkef0sNnJ9AO5terGcbcQoiO\n9iYIFrCEsPDfAW5e4J8L2sLsrRuPIX4AKrkZ48QUHz/zAfAs5YZ5EJPmrzoK\nF4Bule3AQqGdAPCpD1KyRa17QkdbazazSmDc1rXQMzmpgQdvXzX7fo9pB4nn\nZ8Bju6d18vYGko8Mml+4fJjl+PuHoT5hrCGYDjoZvccZM8Vjsq9ebR/cTQwn\nl+HWDkgGfF9rg8bu3O1AYOpFl+IgqqXUqQTvHyhplTBJvgfxXR2dEJcLGZVS\nPZQpkfgqo0T/nCyRWI1o3nUMY0EN+eujejpuaFplfXBP8WIxGYE9WHYq5bh5\nCTiMKwjxVA9cMOUgJUz6Qq9sD9AjliNSveA22AC/lQvJmZaVk/nurvzjk6st\n4DN4PHIg3NRCIKxCcVdqSkelUm5YUPQFRR15UlcrPg8yurkHbmzGh1YkKdRS\nqmS8\r\n=Y749\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPsnat2mzD0XJNP3gcOmyauQxWnJVE/jnHNedfFf0l5QIgVAD8A9BjFKAjPXkFQfuaqor0oI2TrQXbQCFfzygunyY="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.0.0-3_1561913781393_0.7681373513543202"},"_hasShrinkwrap":false},"5.1.0-0":{"name":"typesafe-actions","version":"5.1.0-0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p ./tsconfig.build.json --noEmit","tsc:watch":"tsc -p ./tsconfig.build.json --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p ./tsconfig.build.json && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"3.0.9","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.10.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.1.2","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.8.0-dev.20191026"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"9ab5ba478d3b9daf9d8f20d34fd3f91abaf589c4","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.1.0-0","_nodeVersion":"10.7.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-u7srBxSmQE9gsJbAnRpYYRm38ZGFrmBJcBsghCQIcV6cYZ3TSvdv5YRz9Kk9VYkBD9D+8h8+m7i+YXLkLZXLVQ==","shasum":"3e7df04103246b079ccb58673f39ccdbc16cdd86","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.1.0-0.tgz","fileCount":24,"unpackedSize":152438,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdt0tGCRA9TVsSAnZWagAAlzEP/iwdkejDXIy+T8QyhiUR\nAFoI1gNvTsd7NgyM3HAvEt/kFaHilKLPp2yNoiSIPuuBVQAl/3xQHqGj+GOF\nF1zmp5WbTRvF5nvQCKqYAno/hN801AranjG8TBAtPNE6yYe5LCTezJsOlf3s\nGzlN9urOVMmF+SD1eeHl2Mv1MoURjr+T509WEY4tlLqLoZHZps5O26gBIWC4\nhZRhELrWuj6YCcN17gR8HSYtFQr/vcxh281gbla0Hb0WdO/Em5Joo4+MN4A5\nhAe/YcaRtJ4VyHKkCki2VSPWrx8KFjKphy6302R4eQWJXetI5Vatz3Tunh89\ndQdy9W3Qqg5sF93F48exK6/PAMYPn/ezLSE77TNLanUbcWMzBHCj+R1VlxGM\nP0+RcvqlhB/Z15QBWjJgzUGMai6+q8aL78ZjoWlmXz3n3mckVjG+YzL2xXsm\nmNuOXZZSfUPhuGJx8QQ6yCMjQEpDZWb8uAsFsiOAmYfuwVf5Ps6bc2qAhijL\nacUH6XA/Mp8AQV71Nh3o/f8xQVa2W+MVZ5XxbIn40fgIuII+xYYMJBOxKBt3\n+XUq39uIIfDZsZRLTeZNFAUaAsMGSV7AG1hMWRHlTpnHpIrMrKeir28s+22v\nFPE6qeM7nOw0W5MWFOYsZmF8BpCk8sMZUZ4iV5gjwbdax/BDSKhkFDjQuTxB\nGtyh\r\n=lVPJ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDJ5p8safU1AkrUCNg9jdFHUyy/R513YWVIPoto86p7BwIhAM3B8A6I69f+1UpPruOySUp+mDot1l5PqGSUQ/a+j3NX"}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.1.0-0_1572293446035_0.4371427623434778"},"_hasShrinkwrap":false},"5.1.0-1":{"name":"typesafe-actions","version":"5.1.0-1","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p ./tsconfig.build.json --noEmit","tsc:watch":"tsc -p ./tsconfig.build.json --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p ./tsconfig.build.json && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.4.5","@babel/preset-env":"7.4.5","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.1","core-js":"3.1.4","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"3.0.9","jest":"21.2.1","prettier":"1.18.2","rollup":"1.13.1","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.0.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.0.4","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.10.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.1.2","ts-jest":"21.2.4","tslint":"5.18.0","typescript":"3.8.0-dev.20191026"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"5c6af39d6797feea3c5ccc39b9ee34603e7d20e8","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.1.0-1","_nodeVersion":"10.7.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-I8tZTv15SFTNO+1xfIuINgm5OWm2WBn4eM38UPqkmYvIC4nEGWpPpGtlWeYfifnIlgydzlfq86uBUNIgvYZ/BA==","shasum":"aae51bf16a032cc887978ffb76f4fc8ee223a40b","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.1.0-1.tgz","fileCount":24,"unpackedSize":151356,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJduAqUCRA9TVsSAnZWagAAZHwP/jZn4j2W4kONQHMU4r3d\nW6MyHmcKsHi1urKTh6FPjXJKJjgv2509txVf1jft2WH1rUeRAmK/E/keDwaD\nyAMn1FsoFpKG6Su5qlY5rSvqw6XgWDan7VDB+rihnSE7pkhpQA4QDMDKH6z8\nz9kf+Xl0M5EXaUEKfwyHnUDnoU3/i4IJqP4y3IqQRqn1y8ofchPmaF2AkaGi\nlIGlMhjJ7YVJnSi7qWc47SbbfP12FrFfX7u2FdQj++HeIm5WeDQoQUoOtcsy\nBHIYRoddy+I8++cQFjrNWvTkub1to8WXNMcB9FveqzO32c3tpme1lUk8/HWU\n3HcN8XmIR2s048oZ7PqKR/XBEjVSLGe9b/NBU46w60Vjnp3Oea+JXGSgswpK\nnqZSn17hwfwZhfq5tCTFcACQhjMTzykDXSwi+0bAHXwHmLNyjisoZ3Hz3fBl\nSg0SOxPdH4QuuA/VIbYc74hnp+XBUUT0A5g8wXwy1NoZEgobylNF+XNPNjqZ\nCvGJ/Vj8gfDUXN4exNok+pIKglpc/F5rTOQjCao9OVj2CY7bXbM1bA60EosP\nYDuVhW24pTZEX0lxcTxNbBOXYpyzTf9NhI8ZaFsKg8hDlVoELOchzdV55XGH\nD1OP3dN9i4+n0GgNDW/KqQq1G+griar03zbE0oAR4fWdc8foRsdziW6ohbLV\natsp\r\n=Iqfl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLuznxnqOGVgPACeCl3nvYtAF3Wj74Ap3ECR4RvTTPkQIgTks3/mc/mHvERvymP85G5ObDKgOcEprNnRCubEWaAh0="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.1.0-1_1572342420076_0.33310631752202857"},"_hasShrinkwrap":false},"5.1.0":{"name":"typesafe-actions","version":"5.1.0","description":"Typesafe Action Creators for Redux / Flux Architectures (in TypeScript)","author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"homepage":"https://github.com/piotrwitek/typesafe-actions","license":"MIT","types":"dist/index.d.ts","main":"index.js","module":"dist/typesafe-actions.es.production.js","browser":"dist/typesafe-actions.umd.production.js","engines":{"node":">= 4"},"husky":{"hooks":{"pre-push":"npm run prettier:fix && npm run lint && npm run tsc && npm run test:update && npm run doctoc"}},"scripts":{"ci-check":"npm run prettier && npm run lint && npm run tsc && npm run test","reinstall":"rm -rf node_modules/ dist/ && npm install","prettier":"prettier --list-different 'src/**/*.ts' || (echo '\nPlease fix code formatting by running:\nnpm run prettier:fix\n'; exit 1)","prettier:fix":"prettier --write 'src/**/*.ts'","lint":"tslint --project './tsconfig.json'","tsc":"tsc -p ./tsconfig.build.json --noEmit","tsc:watch":"tsc -p ./tsconfig.build.json --noEmit -w","test":"jest --config jest.config.json && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}} --check","test:update":"jest --config jest.config.json --no-cache -u && dts-jest-remap ./src/*.spec.ts --rename {{basename}}.snap.{{extname}}","test:watch":"jest --config jest.config.json --watch","doctoc":"doctoc --maxlevel=4 README.md","prebuild":"rm -rf dist/ .size-snapshot.json && tsc -p ./tsconfig.declaration.json","build":"tsc -p ./tsconfig.build.json && rollup -c","postbuild":"rm -rf out","prepublishOnly":"npm run reinstall && npm run ci-check && npm run build","benchmark:10":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/10-actions.ts  && rm -rf out","benchmark:150":"node --max-old-space-size=8000 ./node_modules/.bin/tsc --diagnostics --outDir out benchmarks/150-actions.ts && rm -rf out"},"devDependencies":{"@babel/core":"7.6.4","@babel/preset-env":"7.6.3","@types/jest":"21.1.10","babel-plugin-annotate-pure-calls":"0.4.0","babel-plugin-dev-expression":"0.2.2","core-js":"3.3.6","doctoc":"1.4.0","dts-jest":"22.0.4","husky":"3.0.9","jest":"21.2.1","prettier":"1.18.2","rollup":"1.26.3","rollup-plugin-babel":"4.3.3","rollup-plugin-commonjs":"10.1.0","rollup-plugin-json":"4.0.0","rollup-plugin-node-resolve":"5.2.0","rollup-plugin-replace":"2.2.0","rollup-plugin-size-snapshot":"0.10.0","rollup-plugin-sourcemaps":"0.4.2","rollup-plugin-terser":"5.1.2","ts-jest":"22.4.6","tslint":"5.20.0","typescript":"3.8.0-dev.20191026"},"keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"gitHead":"575b8b2d1b0b15b07131acff1d3c80a2f5870965","bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"_id":"typesafe-actions@5.1.0","_nodeVersion":"10.7.0","_npmVersion":"6.12.0","dist":{"integrity":"sha512-bna6Yi1pRznoo6Bz1cE6btB/Yy8Xywytyfrzu/wc+NFW3ZF0I+2iCGImhBsoYYCOWuICtRO4yHcnDlzgo1AdNg==","shasum":"9afe8b1e6a323af1fd59e6a57b11b7dd6623d2f1","tarball":"https://registry.npmjs.org/typesafe-actions/-/typesafe-actions-5.1.0.tgz","fileCount":32,"unpackedSize":296277,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdveGWCRA9TVsSAnZWagAATW4P/2+WdO6XDGFakV1feVp0\nj62afLscHMHZ6kAfeyhOEtL8JcufIhgMOQeNG/jwnFglYtFuqz5xuZMOar/s\n9yhr/uoneVTmSa5PKODWC5BiP8DwdNsPhYjqa0stY5nmrMoioqYJP24bVMkL\nLP6MC8X+TDWGz4WANYYuEPF3RxprrB4YD0+5lbvHicfGn/KO26jCef2ifSAM\nUzG3eoktTKZfjTTcivfmkw5mNew1Pe4WG8WarPX7RLjmW277XWlHLxgMt2ii\nVRoCdMANHeScqsO4ds4+XJdqVtL0BFcwt5JCA6CAtBwrFfYhudqqNIcsi/BJ\nqIwsnDbwWGVqZKa7hqSih9195ZlOpVaEDWumnJtnZlcMCJPNwQ7CkSRcdYWX\no2aPIggqq36QMto+1MTDvMhZvpSDho0BLO48hsE3t26VSPO25V0u/oHHxBsh\njka3fuPF7mz9vRsIazVBfNqvlcnHeCBfrnB866nTiR1vm9KFFejGONp50S/P\nBZDPlGgotHRHATvn5m9AohQCoW188kUsOttereOddEnOKeiMCRA9oMX/udjk\ng5aHw/6fqimyqLwCKjNE6+CtF8rDKNCPTzUXMmMjZZpSjtpZVbn405XqcZUg\nKR/LNaXy6pP3niEmjGcD1XjrLJywwu+cCUW2KAHsylxpUsnxpVhACXMvJ0Ny\nbh9m\r\n=Yiki\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCy89YnxylmpvR0L/2u1+BlJRdwEdOcspzVCvrvnDOjqwIgdYsthjfpy20BVXIG0N8eyfSjiOynzP4sKd1IWOZNy9I="}]},"maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"_npmUser":{"name":"piotrwitek","email":"piotrek.witek@gmail.com"},"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/typesafe-actions_5.1.0_1572725141545_0.658061143330523"},"_hasShrinkwrap":false}},"readme":"<div align=\"center\">\n\n# typesafe-actions\n\nTypesafe utilities designed to reduce types **verbosity**\nand **complexity** in Redux Architecture.\n\n_This library is part of the [React & Redux TypeScript Guide](https://github.com/piotrwitek/react-redux-typescript-guide)_ ecosystem :book:  \n\n[![Latest Stable Version](https://img.shields.io/npm/v/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dm/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![NPM Downloads](https://img.shields.io/npm/dt/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n[![Bundlephobia Size](https://img.shields.io/bundlephobia/minzip/typesafe-actions.svg)](https://www.npmjs.com/package/typesafe-actions)\n\n[![Build Status](https://semaphoreci.com/api/v1/piotrekwitek/typesafe-actions/branches/master/shields_badge.svg)](https://semaphoreci.com/piotrekwitek/typesafe-actions)\n[![Dependency Status](https://img.shields.io/david/piotrwitek/typesafe-actions.svg)](https://david-dm.org/piotrwitek/typesafe-actions)\n[![License](https://img.shields.io/npm/l/typesafe-actions.svg?style=flat)](https://david-dm.org/piotrwitek/typesafe-actions?type=peer)\n[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/typesafe-actions)\n\n_Found it useful? Want more updates?_\n\n[**Show your support by giving a :star:**](https://github.com/piotrwitek/typesafe-actions/stargazers)\n\n<!-- _Make a one time or a monthly donation to join [supporters](https://www.buymeacoffee.com/piotrekwitek)_ -->\n\n<a href=\"https://www.buymeacoffee.com/piotrekwitek\">\n  <img src=\"https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png\" alt=\"Buy Me a Coffee\">\n</a>\n\n<!-- _Or become a [sponsor](..) to get your logo with a link on our README_ -->\n\n<a href=\"https://www.patreon.com/piotrekwitek\">\n  <img src=\"https://c5.patreon.com/external/logo/become_a_patron_button@2x.png\" alt=\"Become a Patron\" width=\"160\">\n</a>\n\n<br/><hr/>\n\n## What's new?\n\n:tada: _Now updated to support **TypeScript v3.7**_ :tada:\n\n:warning: Library was recently updated to v5 :warning:\n<br/>*Current API Docs and Tutorial are outdated (from v4), so temporarily please use this issue as [v5.x.x API Docs](https://github.com/piotrwitek/typesafe-actions/issues/143).*\n\n<hr/><br/>\n\n</div>\n\n### **Features**\n- Easily create completely typesafe [Actions](#action-creators-api) or even [Async Actions](#createasyncaction)\n- No boilerplate and completely typesafe [Reducers](#reducer-creators-api)\n- Game-changing [Helper Types](#type-helpers-api) for Redux\n\n### **Playgrounds & Examples**\n\n- Todo-App playground: [Codesandbox](https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox)\n- React, Redux, TypeScript - RealWorld App: [Github](https://github.com/piotrwitek/react-redux-typescript-realworld-app) | [Demo](https://react-redux-typescript-realworld-app.netlify.com/)\n\n### **Goals**\n\n- **Secure and Minimal** - no third-party dependencies, according to `size-snapshot` (Minified: 3.48 KB, Gzipped: 1.03 KB), check also on [bundlephobia](https://bundlephobia.com/result?p=typesafe-actions)\n- **Optimized** - distribution packages bundled in 3 different formats (`cjs`, `esm` and `umd`) with separate bundles for dev & prod (same as `react`)\n- **Quality** - complete test-suite for an entire API surface containing regular runtime tests and extra type-tests to guarantee **type soundness** and to prevent regressions in the future TypeScript versions\n- **Performance** - integrated performance benchmarks to guarantee that the computational complexity of types are in check and there are no slow-downs when your application grow `npm run benchmark:XXX`\n\n---\n\n## Table of Contents\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n\n\n- [Installation](#installation)\n- [Tutorial v4 (v5 is WIP #188)](#tutorial-v4-v5-is-wip-188)\n  - [Constants](#constants)\n  - [Actions](#actions)\n    - [1. Basic actions](#1-basic-actions)\n    - [2. FSA compliant actions](#2-fsa-compliant-actions)\n    - [3. Custom actions (non-standard use-cases)](#3-custom-actions-non-standard-use-cases)\n  - [Action Helpers](#action-helpers)\n    - [Using action-creators instances instead of type-constants](#using-action-creators-instances-instead-of-type-constants)\n    - [Using regular type-constants](#using-regular-type-constants)\n  - [Reducers](#reducers)\n    - [Extending internal types to enable type-free syntax with `createReducer`](#extending-internal-types-to-enable-type-free-syntax-with-createreducer)\n    - [Using createReducer API with type-free syntax](#using-createreducer-api-with-type-free-syntax)\n    - [Alternative usage with regular switch reducer](#alternative-usage-with-regular-switch-reducer)\n  - [Async-Flows](#async-flows)\n    - [With `redux-observable` epics](#with-redux-observable-epics)\n    - [With `redux-saga` sagas](#with-redux-saga-sagas)\n- [API Docs v4 (v5 is WIP #189)](#api-docs-v4-v5-is-wip-189)\n  - [Action-Creators API](#action-creators-api)\n    - [`action`](#action)\n    - [`createAction`](#createaction)\n    - [`createStandardAction`](#createstandardaction)\n    - [`createCustomAction`](#createcustomaction)\n    - [`createAsyncAction`](#createasyncaction)\n  - [Reducer-Creators API](#reducer-creators-api)\n    - [`createReducer`](#createreducer)\n  - [Action-Helpers API](#action-helpers-api)\n    - [`getType`](#gettype)\n    - [`isActionOf`](#isactionof)\n    - [`isOfType`](#isoftype)\n  - [Type-Helpers API](#type-helpers-api)\n    - [`ActionType`](#actiontype)\n    - [`StateType`](#statetype)\n- [Migration Guides](#migration-guides)\n  - [`v4.x.x` to `v5.x.x`](#v4xx-to-v5xx)\n  - [`v3.x.x` to `v4.x.x`](#v3xx-to-v4xx)\n  - [`v2.x.x` to `v3.x.x`](#v2xx-to-v3xx)\n  - [`v1.x.x` to `v2.x.x`](#v1xx-to-v2xx)\n  - [Migrating from `redux-actions` to `typesafe-actions`](#migrating-from-redux-actions-to-typesafe-actions)\n- [Compatibility Notes](#compatibility-notes)\n- [Recipes](#recipes)\n  - [Restrict Meta type in `action` creator](#restrict-meta-type-in-action-creator)\n- [Compare to others](#compare-to-others)\n  - [`redux-actions`](#redux-actions)\n- [Motivation](#motivation)\n- [Contributing](#contributing)\n- [Funding Issues](#funding-issues)\n- [License](#license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n<hr/>\n\n## Installation\n\n```bash\n# NPM\nnpm install typesafe-actions\n\n# YARN\nyarn add typesafe-actions\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Tutorial v4 (v5 is WIP [#188](https://github.com/piotrwitek/typesafe-actions/issues/188))\n\nTo showcase the flexibility and the power of the **type-safety** provided by this library, let's build the most common parts of a typical todo-app using a Redux architecture:\n\n> **WARNING**  \n> Please make sure that you are familiar with the following concepts of programming languages to be able to follow along: [Type Inference](https://www.typescriptlang.org/docs/handbook/type-inference.html), [Control flow analysis](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#control-flow-based-type-analysis), [Tagged union types](https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#tagged-union-types), [Generics](https://www.typescriptlang.org/docs/handbook/generics.html) and [Advanced Types](https://www.typescriptlang.org/docs/handbook/advanced-types.html).\n\n[⇧ back to top](#table-of-contents)\n\n### Constants\n\n> **RECOMMENDATION:**  \n> When using `typesafe-actions` in your project you won't need to export and reuse **string constants**. It's because **action-creators** created by this library have static property with **action type** that you can easily access using **actions-helpers** and then use it in reducers, epics, sagas, and basically any other place. This will simplify your codebase and remove some boilerplate code associated with the usage of **string constants**. Check our `/codesandbox` application to learn some best-practices to create such codebase.\n\n**Limitations of TypeScript when working with string constants** - when using **string constants** as action `type` property, please make sure to use **simple string literal assignment with const**. This limitation is coming from the type-system, because all the **dynamic string operations** (e.g. string concatenation, template strings and also object used as a map) will widen the literal type to its super-type, `string`. As a result this will break contextual typing for **action** object in reducer cases.\n\n```ts\n// Example file: './constants.ts'\n\n// WARNING: Incorrect usage\nexport const ADD = prefix + 'ADD'; // => string\nexport const ADD = `${prefix}/ADD`; // => string\nexport default {\n   ADD: '@prefix/ADD', // => string\n}\n\n// Correct usage\nexport const ADD = '@prefix/ADD'; // => '@prefix/ADD'\nexport const TOGGLE = '@prefix/TOGGLE'; // => '@prefix/TOGGLE'\nexport default ({\n  ADD: '@prefix/ADD', // => '@prefix/ADD'\n} as const) // working in TS v3.4 and above => https://github.com/Microsoft/TypeScript/pull/29510\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Actions\n\nDifferent projects have different needs, and conventions vary across teams, and this is why `typesafe-actions` was designed with flexibility in mind. It provides three different major styles so you can choose whichever would be the best fit for your team.\n\n#### 1. Basic actions\n`action` and `createAction` are creators that can create **actions** with predefined properties ({ type, payload, meta }). This make them concise but also opinionated.\n \nImportant property is that resulting **action-creator** will have a variadic number of arguments and preserve their semantic names `(id, title, amount, etc...)`.\n\nThis two creators are very similar and the only real difference is that `action` **WILL NOT WORK** with **action-helpers**.\n\n```ts\nimport { action, createAction } from 'typesafe-actions';\n\nexport const add = (title: string) => action('todos/ADD', { id: cuid(), title, completed: false });\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n\nexport const add = createAction('todos/ADD', action => {\n  // Note: \"action\" callback does not need \"type\" parameter\n  return (title: string) => action({ id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 2. FSA compliant actions\nThis style is aligned with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action), so your **action** object shape is constrained to `({ type, payload, meta, error })`. It is using **generic type arguments** for `meta` and `payload` to simplify creation of type-safe action-creators.\n\nIt is important to notice that in the resulting **action-creator** arguments are also constrained to the predefined: `(payload, meta)`, making it the most opinionated creator.\n\n> **TIP**: This creator is the most compatible with `redux-actions` in case you are migrating.\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\nexport const toggle = createStandardAction('todos/TOGGLE')<string>();\n// toggle: (payload: string) => { type: \"todos/TOGGLE\"; payload: string; }\n\nexport const add = createStandardAction('todos/ADD').map(\n  (title: string) => ({\n    payload: { id: cuid(), title, completed: false },\n  })\n);\n// add: (payload: string) => { type: \"todos/ADD\"; payload: { id: string, title: string, completed: boolean; }; }\n```\n\n#### 3. Custom actions (non-standard use-cases)\n\nThis approach will give us the most flexibility of all creators, providing a variadic number of named parameters and custom properties on **action** object to fit all the custom use-cases.\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('todos/ADD', type => {\n  return (title: string) => ({ type, id: cuid(), title, completed: false });\n});\n// add: (title: string) => { type: \"todos/ADD\"; id: string; title: string; completed: boolean; }\n```\n\n> **TIP**: For more examples please check the [API Docs](#table-of-contents).\n\n> **RECOMMENDATION**  \n> Common approach is to create a `RootAction` in the central point of your redux store - it will represent all possible action types in your application. You can even merge it with third-party action types as shown below to make your model complete.\n\n```ts\n// types.d.ts\n// example of including `react-router` actions in `RootAction`\nimport { RouterAction, LocationChangeAction } from 'react-router-redux';\nimport { TodosAction } from '../features/todos';\n\ntype ReactRouterAction = RouterAction | LocationChangeAction;\n\nexport type RootAction =\n  | ReactRouterAction\n  | TodosAction;\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Action Helpers\n\nNow I want to show you **action-helpers** and explain their use-cases. We're going to implement a side-effect responsible for showing a success toast when user adds a new todo.\n\nImportant thing to notice is that all these helpers are acting as a **type-guard** so they'll narrow **tagged union type** (`RootAction`) to a specific action type that we want.\n\n#### Using action-creators instances instead of type-constants\n\nInstead of **type-constants** we can use **action-creators** instance to match specific actions in reducers and epics cases. It works by adding a static property on **action-creator** instance which contains the `type` string. \n\nThe most common one is `getType`, which is useful for regular reducer switch cases:\n\n```ts\n  switch (action.type) {\n    case getType(todos.add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\nThen we have the `isActionOf` helper which accept **action-creator** as first parameter matching actions with corresponding type passed as second parameter (it's a curried function).\n\n```ts\n// epics.ts\nimport { isActionOf } from 'typesafe-actions';\n\nimport { add } from './actions';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, state$, { toastService }) =>\n  action$.pipe(\n    filter(isActionOf(add)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      toastService.success(...);\n    })\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isActionOf([add, toggle])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n#### Using regular type-constants\nAlternatively if your team prefers to use regular **type-constants** you can still do that.\n\nWe have an equivalent helper (`isOfType`) which accept **type-constants** as parameter providing the same functionality.\n\n```ts\n// epics.ts\nimport { isOfType } from 'typesafe-actions';\n\nimport { ADD } from './constants';\n\nconst addTodoToast: Epic<RootAction, RootAction, RootState, Services> = (action$, state$, { toastService }) =>\n  action$.pipe(\n    filter(isOfType(ADD)),\n    tap(action => { // here action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n  // Works with multiple actions! (with type-safety up to 5)\n  action$.pipe(\n    filter(isOfType([ADD, TOGGLE])) // here action type is narrowed to a smaller union:\n    // { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/TOGGLE\"; payload: string; }\n```\n\n> **TIP:** you can use action-helpers with other types of conditional statements.\n\n```ts\nimport { isActionOf, isOfType } from 'typesafe-actions';\n\nif (isActionOf(actions.add, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n// or with type constants\nif (isOfType(types.ADD, action)) {\n  // here action is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Reducers\n\n#### Extending internal types to enable type-free syntax with `createReducer`\n\nWe can extend internal types of `typesafe-actions` module with `RootAction` definition of our application so that you don't need to pass generic type arguments with `createReducer` API:\n\n```ts\n// types.d.ts\nimport { StateType, ActionType } from 'typesafe-actions';\n\nexport type RootAction = ActionType<typeof import('./actions').default>;\n\ndeclare module 'typesafe-actions' {\n  interface Types {\n    RootAction: RootAction;\n  }\n}\n\n// now you can use\ncreateReducer(...)\n// instead of\ncreateReducer<State, Action>(...)\n```\n\n#### Using createReducer API with type-free syntax\n\nWe can prevent a lot of boilerplate code and type errors using this powerfull and completely typesafe API.\n\nUsing handleAction chain API:\n```ts\n// using action-creators\nconst counterReducer = createReducer(0)\n  // state and action type is automatically inferred and return type is validated to be exact type\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(add, ... // <= error is shown on duplicated or invalid actions\n  .handleAction(increment, (state, _) => state + 1)\n  .handleAction(... // <= error is shown when all actions are handled\n  \n  // or handle multiple actions using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer(0)\n  .handleAction('ADD', (state, action) => state + action.payload)\n  .handleAction('INCREMENT', (state, _) => state + 1);\n  \ncounterReducer(0, add(4)); // => 4\ncounterReducer(0, increment()); // => 1\n```\n\n#### Alternative usage with regular switch reducer\n\nFirst we need to start by generating a **tagged union type** of actions (`TodosAction`). It's very easy to do by using `ActionType` **type-helper**.\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n```\n\nNow we define a regular reducer function by annotating `state` and `action` arguments with their respective types (`TodosAction` for action type).\n\n```ts\nexport default (state: Todo[] = [], action: TodosAction) => {\n```\n\nNow in the switch cases we can use the `type` property of action to narrowing the union type of `TodosAction` to an action that is corresponding to that type.\n\n```ts\n  switch (action.type) {\n    case getType(add):\n      // below action type is narrowed to: { type: \"todos/ADD\"; payload: Todo; }\n      return [...state, action.payload];\n    ...\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Async-Flows\n\n#### With `redux-observable` epics\n\nTo handle an async-flow of http request lets implement an `epic`. The `epic` will call a remote API using an injected `todosApi` client, which will return a Promise that we'll need to handle by using three different actions that correspond to triggering, success and failure.\n\nTo help us simplify the creation process of necessary action-creators, we'll use `createAsyncAction` function providing us with a nice common interface object `{ request: ... , success: ... , failure: ... }` that will nicely fit with the functional API of `RxJS`.\nThis will mitigate **redux verbosity** and greatly reduce the maintenance cost of type annotations for **actions** and **action-creators** that would otherwise be written explicitly.\n\n```ts\n// actions.ts\nimport { createAsyncAction } from 'typesafe-actions';\n\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE',\n  'FETCH_TODOS_CANCEL'\n)<string, Todo[], Error, string>();\n\n// epics.ts\nimport { fetchTodosAsync } from './actions';\n\nconst fetchTodosFlow: Epic<RootAction, RootAction, RootState, Services> = (action$, state$, { todosApi }) =>\n  action$.pipe(\n    filter(isActionOf(fetchTodosAsync.request)),\n    switchMap(action =>\n      from(todosApi.getAll(action.payload)).pipe(\n        map(fetchTodosAsync.success),\n        catchError((message: string) => of(fetchTodosAsync.failure(message))),\n        takeUntil(action$.pipe(filter(isActionOf(fetchTodosAsync.cancel)))),\n      )\n    );\n```\n\n#### With `redux-saga` sagas\nWith sagas it's not possible to achieve the same degree of type-safety as with epics because of limitations coming from `redux-saga` API design.\n\nTypescript issues:\n- [Typescript does not currently infer types resulting from a `yield` statement](https://github.com/Microsoft/TypeScript/issues/2983) so you have to manually assert the type  e.g. `const response: Todo[] = yield call(...`\n\n*Here is the latest recommendation although it's not fully optimal. If you managed to cook something better, please open an issue to share your finding with us.*\n\n```ts\nimport { createAsyncAction, createReducer } from 'typesafe-actions';\nimport { put, call, takeEvery } from 'redux-saga/effetcs';\n\n// Create the set of async actions\nconst fetchTodosAsync = createAsyncAction(\n  'FETCH_TODOS_REQUEST',\n  'FETCH_TODOS_SUCCESS',\n  'FETCH_TODOS_FAILURE'\n)<string, Todo[], Error>();\n\n// Handle request saga\nfunction* addTodoSaga(action: ReturnType<typeof fetchTodosAsync.request>): Generator {\n  try {\n    const response: Todo[] = yield call(todosApi.getAll, action.payload);\n\n    yield put(fetchTodosAsync.success(response));\n  } catch (err) {\n    yield put(fetchTodosAsync.failure(err));\n  }\n}\n\n// Main saga\nfunction* mainSaga() {\n    yield all([\n        takeEvery(fetchTodosAsync.request, addTodoSaga),\n    ]);\n}\n\n// Handle success reducer\nexport const todoReducer = createReducer({})\n    .handleAction(fetchTodosAsync.success, (state, action) => ({ ...state, todos: action.payload }));\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## API Docs v4 (v5 is WIP [#189](https://github.com/piotrwitek/typesafe-actions/issues/189))\n\n### Action-Creators API\n\n#### `action`\n\n_Simple **action factory function** to simplify creation of type-safe actions._\n\n> **WARNING**:  \n> This approach will **NOT WORK** with **action-helpers** (such as `getType` and `isActionOf`) because it is creating **action objects** while all the other creator functions are returning **enhanced action-creators**.\n\n```ts\naction(type, payload?, meta?, error?)\n```\n\nExamples:\n[> Advanced Usage Examples](src/action.spec.ts)\n\n```ts\nconst increment = () => action('INCREMENT');\n// { type: 'INCREMENT'; }\n\nconst createUser = (id: number, name: string) =>\n  action('CREATE_USER', { id, name });\n// { type: 'CREATE_USER'; payload: { id: number; name: string }; }\n\nconst getUsers = (params?: string) =>\n  action('GET_USERS', undefined, params);\n// { type: 'GET_USERS'; meta: string | undefined; }\n```\n\n> **TIP**: Starting from TypeScript v3.4 you can achieve similar results using new `as const` operator.\n\n```ts\nconst increment = () => ({ type: 'INCREMENT' } as const);\n```\n\n#### `createAction`\n\n_Create an enhanced action-creator with unlimited number of arguments._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have predefined properties `({ type, payload, meta })`\n\n```ts\ncreateAction(type)\ncreateAction(type, actionCallback => {\n  return (namedArg1, namedArg2, ...namedArgN) => actionCallback(payload?, meta?)\n})\n```\n> **TIP**: Injected `actionCallback` argument is similar to `action` API but doesn't need the \"type\" parameter\n\nExamples:\n[> Advanced Usage Examples](src/create-action.spec.ts)\n\n```ts\nimport { createAction } from 'typesafe-actions';\n\n// - with type only\nconst increment = createAction('INCREMENT');\ndispatch(increment());\n// { type: 'INCREMENT' };\n\n// - with type and payload\nconst add = createAction('ADD', action => {\n  return (amount: number) => action(amount);\n});\ndispatch(add(10));\n// { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getTodos = createAction('GET_TODOS', action => {\n  return (params: Params) => action(undefined, params);\n});\ndispatch(getTodos('some_meta'));\n// { type: 'GET_TODOS', meta: Params }\n\n// - and finally with type, payload and meta\nconst getTodo = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\ndispatch(getTodo('some_id', 'some_meta'));\n// { type: 'GET_TODO', payload: string, meta: string }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createStandardAction`\n\n_Create an enhanced action-creator compatible with [Flux Standard Action](https://github.com/redux-utilities/flux-standard-action) to reduce boilerplate and enforce convention._\n- Resulting action-creator have predefined arguments `(payload, meta)`\n- Returned action object have predefined properties `({ type, payload, meta, error })`\n- But it also contains a `.map()` method that allow to map `(payload, meta)` arguments to a custom action object `({ customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateStandardAction(type)()\ncreateStandardAction(type)<TPayload, TMeta?>()\ncreateStandardAction(type).map((payload, meta) => ({ customProp1, customProp2, ...customPropN }))\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-standard-action.spec.ts)\n\n```ts\nimport { createStandardAction } from 'typesafe-actions';\n\n// Very concise with use of generic type arguments\n// - with type only\nconst increment = createStandardAction('INCREMENT')();\nconst increment = createStandardAction('INCREMENT')<undefined>();\nincrement(); // { type: 'INCREMENT' } (no parameters are required)\n\n\n// - with type and payload\nconst add = createStandardAction('ADD')<number>();\nadd(10); // { type: 'ADD', payload: number }\n\n// - with type and meta\nconst getData = createStandardAction('GET_DATA')<undefined, string>();\ngetData(undefined, 'meta'); // { type: 'GET_DATA', meta: string }\n\n// - and finally with type, payload and meta\nconst getData = createStandardAction('GET_DATA')<number, string>();\ngetData(1, 'meta'); // { type: 'GET_DATA', payload: number, meta: string }\n\n// Can map payload and meta arguments to a custom action object\nconst notify = createStandardAction('NOTIFY').map(\n  (payload: string, meta: Meta) => ({\n    from: meta.username,\n    message: `${username}: ${payload}`,\n    messageType: meta.type,\n    datetime: new Date(),\n  })\n);\n\ndispatch(notify('Hello!', { username: 'Piotr', type: 'announcement' }));\n// { type: 'NOTIFY', from: string, message: string, messageType: MessageType, datetime: Date }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createCustomAction`\n\n_Create an enhanced action-creator with unlimited number of arguments and custom properties on action object._\n- Resulting action-creator will preserve semantic names of their arguments  `(id, title, amount, etc...)`.\n- Returned action object have custom properties `({ type, customProp1, customProp2, ...customPropN })`\n\n```ts\ncreateCustomAction(type, type => {\n  return (namedArg1, namedArg2, ...namedArgN) => ({ type, customProp1, customProp2, ...customPropN })\n})\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-action-with-type.spec.ts)\n\n```ts\nimport { createCustomAction } from 'typesafe-actions';\n\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\ndispatch(add(1));\n// { type: \"CUSTOM\"; customProp1: number; customProp2: number; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `createAsyncAction`\n\n_Create an object containing three enhanced action-creators to simplify handling of async flows (e.g. network request - request/success/failure)._\n\n```ts\ncreateAsyncAction(\n  requestType, successType, failureType, cancelType?\n)<TRequestPayload, TSuccessPayload, TFailurePayload, TCancelPayload?>()\n```\n\n##### `AsyncActionCreator`\n\n```ts\ntype AsyncActionCreator<\n  [TRequestType, TRequestPayload],\n  [TSuccessType, TSuccessPayload],\n  [TFailureType, TFailurePayload],\n  [TCancelType, TCancelPayload]?\n> = {\n  request: StandardActionCreator<TRequestType, TRequestPayload>,\n  success: StandardActionCreator<TSuccessType, TSuccessPayload>,\n  failure: StandardActionCreator<TFailureType, TFailurePayload>,\n  cancel?: StandardActionCreator<TCancelType, TCancelPayload>,\n}\n```\n\n> **TIP**: Using `undefined` as generic type parameter you can make the action-creator function require NO parameters.\n\nExamples:\n[> Advanced Usage Examples](src/create-async-action.spec.ts)\n\n```ts\nimport { createAsyncAction, AsyncActionCreator } from 'typesafe-actions';\n\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n)<string, User[], Error>();\n\ndispatch(fetchUsersAsync.request(params));\n\ndispatch(fetchUsersAsync.success(response));\n\ndispatch(fetchUsersAsync.failure(err));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error]\n  >\n) => a;\nfn(fetchUsersAsync);\n\n// There is 4th optional argument to declare cancel action\nconst fetchUsersAsync = createAsyncAction(\n  'FETCH_USERS_REQUEST',\n  'FETCH_USERS_SUCCESS',\n  'FETCH_USERS_FAILURE'\n  'FETCH_USERS_CANCEL'\n)<string, User[], Error, string>();\n\ndispatch(fetchUsersAsync.cancel('reason'));\n\nconst fn = (\n  a: AsyncActionCreator<\n    ['FETCH_USERS_REQUEST', string],\n    ['FETCH_USERS_SUCCESS', User[]],\n    ['FETCH_USERS_FAILURE', Error],\n    ['FETCH_USERS_CANCEL', string]\n  >\n) => a;\nfn(fetchUsersAsync);\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Reducer-Creators API\n\n#### `createReducer`\n\n_Create a typesafe reducer_\n\n```ts\ncreateReducer<TState, TRootAction>(initialState, handlersMap?)\n// or\ncreateReducer<TState, TRootAction>(initialState)\n  .handleAction(actionCreator, reducer)\n  .handleAction([actionCreator1, actionCreator2, ...actionCreatorN], reducer)\n  .handleType(type, reducer)\n  .handleType([type1, type2, ...typeN], reducer)\n```\n\nExamples:\n[> Advanced Usage Examples](src/create-reducer.spec.ts)\n\n> **TIP:** You can use reducer API with a **type-free** syntax by [Extending internal types](#extending-internal-types-to-enable-type-free-syntax-with-createreducer), otherwise you'll have to pass generic type arguments like in below examples\n```ts\n// type-free syntax doesn't require generic type arguments\nconst counterReducer = createReducer(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Object map style:**\n```ts\nimport { createReducer, getType } from 'typesafe-actions'\n\ntype State = number;\ntype Action = { type: 'ADD', payload: number } | { type: 'INCREMENT' };\n\nconst counterReducer = createReducer<State, Action>(0, { \n  ADD: (state, action) => state + action.payload,\n  [getType(increment)]: (state, _) => state + 1,\n})\n```\n\n**Chain API style:**\n```ts\n// using action-creators\nconst counterReducer = createReducer<State, Action>(0)\n  .handleAction(add, (state, action) => state + action.payload)\n  .handleAction(increment, (state, _) => state + 1)\n\n  // handle multiple actions by using array\n  .handleAction([add, increment], (state, action) =>\n    state + (action.type === 'ADD' ? action.payload : 1)\n  );\n\n// all the same scenarios are working when using type-constants\nconst counterReducer = createReducer<State, Action>(0)\n  .handleType('ADD', (state, action) => state + action.payload)\n  .handleType('INCREMENT', (state, _) => state + 1);\n```\n\n**Extend or compose reducers - every operation is completely typesafe:**\n```ts\nconst newCounterReducer = createReducer<State, Action>(0)\n  .handleAction('SUBTRACT', (state, action) => state - action.payload)\n  .handleAction('DECREMENT', (state, _) => state - 1);\n\nconst bigReducer = createReducer<State, Action>(0, {\n  ...counterReducer.handlers, // typesafe\n  ...newCounterReducer.handlers, // typesafe\n  SUBTRACT: decrementReducer.handlers.DECREMENT, // <= error, wrong type\n})\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Action-Helpers API\n\n#### `getType`\n\n_Get the **type** property value (narrowed to literal type) of given enhanced action-creator._\n\n```ts\ngetType(actionCreator)\n```\n\n[> Advanced Usage Examples](src/get-type.spec.ts)\n\nExamples:\n```ts\nimport { getType, createStandardAction } from 'typesafe-actions';\n\nconst add = createStandardAction('ADD')<number>();\n\n// In switch reducer\nswitch (action.type) {\n  case getType(add):\n    // action type is { type: \"ADD\"; payload: number; }\n    return state + action.payload;\n\n  default:\n    return state;\n}\n\n// or with conditional statements\nif (action.type === getType(add)) {\n  // action type is { type: \"ADD\"; payload: number; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isActionOf`\n\n_Check if action is an instance of given enhanced action-creator(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n\n> **WARNING**: Regular action creators and [action](#action) will not work with this helper\n\n```ts\n// can be used as a binary function\nisActionOf(actionCreator, action)\n// or as a curried function\nisActionOf(actionCreator)(action)\n// also accepts an array\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN], action)\n// with its curried equivalent\nisActionOf([actionCreator1, actionCreator2, ...actionCreatorN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-action-of.spec.ts)\n\n```ts\nimport { addTodo, removeTodo } from './todos-actions';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isActionOf(addTodo)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isActionOf([addTodo, removeTodo])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isActionOf(addTodo, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isActionOf([addTodo, removeTodo], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `isOfType`\n\n_Check if action type property is equal given type-constant(s)\n(it will narrow action type to a type of given action-creator(s))_\n\n```ts\n// can be used as a binary function\nisOfType(type, action)\n// or as curried function\nisOfType(type)(action)\n// also accepts an array\nisOfType([type1, type2, ...typeN], action)\n// with its curried equivalent\nisOfType([type1, type2, ...typeN])(action)\n```\n\nExamples:\n[> Advanced Usage Examples](src/is-of-type.spec.ts)\n\n```ts\nimport { ADD, REMOVE } from './todos-types';\n\n// Works with any filter type function (`Array.prototype.filter`, lodash, ramda, rxjs, etc.)\n// - single action\n[action1, action2, ...actionN]\n  .filter(isOfType(ADD)) // only actions with type `ADD` will pass\n  .map((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; }\n    ...\n    \n// - multiple actions\n[action1, action2, ...actionN]\n  .filter(isOfType([ADD, REMOVE])) // only actions with type `ADD` or 'REMOVE' will pass\n  .do((action) => {\n    // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n    ...\n      \n// With conditional statements\n// - single action\nif(isOfType(ADD, action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; }\n}\n// - multiple actions\nif(isOfType([ADD, REMOVE], action)) {\n  return iAcceptOnlyTodoType(action.payload);\n  // action type is { type: \"todos/ADD\"; payload: Todo; } | { type: \"todos/REMOVE\"; payload: Todo; }\n}\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n### Type-Helpers API\nBelow helper functions are very flexible generalizations, works great with nested structures and will cover numerous different use-cases.\n\n#### `ActionType`\n\n_Powerful type-helper that will infer union type from **import * as ...** or **action-creator map** object._\n\n```ts\nimport { ActionType } from 'typesafe-actions';\n\n// with \"import * as ...\"\nimport * as todos from './actions';\nexport type TodosAction = ActionType<typeof todos>;\n// TodosAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n\n// with nested action-creator map case\nconst actions = {\n  action1: createAction('action1'),\n  nested: {\n    action2: createAction('action2'),\n    moreNested: {\n      action3: createAction('action3'),\n    },\n  },\n};\nexport type RootAction = ActionType<typeof actions>;\n// RootAction: { type: 'action1' } | { type: 'action2' } | { type: 'action3' }\n```\n\n[⇧ back to top](#table-of-contents)\n\n#### `StateType`\n\n_Powerful type helper that will infer state object type from **reducer function** and **nested/combined reducers**._\n\n> **WARNING**: working with redux@4+ types\n\n```ts\nimport { combineReducers } from 'redux';\nimport { StateType } from 'typesafe-actions';\n\n// with reducer function\nconst todosReducer = (state: Todo[] = [], action: TodosAction) => {\n  switch (action.type) {\n    case getType(todos.add):\n      return [...state, action.payload];\n    ...\nexport type TodosState = StateType<typeof todosReducer>;\n\n// with nested/combined reducers\nconst rootReducer = combineReducers({\n  router: routerReducer,\n  counters: countersReducer,\n});\nexport type RootState = StateType<typeof rootReducer>;\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Migration Guides\n\n### `v4.x.x` to `v5.x.x`\n\n**Breaking changes:**\n\n1. In `v5` all the deprecated `v4` creator functions are available under `deprecated` named import to help with incremental migration.\n```ts\n// before\nimport { createAction, createStandardAction, createCustomAction } from \"typesafe-actions\"\n\n// after\nimport { deprecated } from \"typesafe-actions\"\nconst { createAction, createStandardAction, createCustomAction } = deprecated;\n```\n\n2. `createStandardAction` was renamed to `createAction` and `.map` method was removed in favor of simpler `redux-actions` style API.\n```ts\n// before\nconst withMappedPayloadAndMeta = createStandardAction(\n  'CREATE_STANDARD_ACTION'\n).map(({ username, message }: Notification) => ({\n  payload: `${username}: ${message}`,\n  meta: { username, message },\n}));\n\n// after\nconst withMappedPayloadAndMeta = createAction(\n  'CREATE_STANDARD_ACTION',\n  ({ username, message }: Notification) => `${username}: ${message}`, // payload creator\n  ({ username, message }: Notification) => ({ username, message }) // meta creator\n)();\n```\n\n3. `v4` version of `createAction` was removed. I suggest to refactor to use a new `createAction` as in point `2`, which was simplified and extended to support `redux-actions` style API.\n```ts\n// before\nconst withPayloadAndMeta = createAction('CREATE_ACTION', resolve => {\n  return (id: number, token: string) => resolve(id, token);\n});\n\n// after\nconst withPayloadAndMeta = createAction(\n  'CREATE_ACTION',\n  (id: number, token: string) => id, // payload creator\n  (id: number, token: string) => token // meta creator\n})();\n```\n\n4. `createCustomAction` - API was greatly simplified, now it's used like this:\n```ts\n// before\nconst add = createCustomAction('CUSTOM', type => {\n  return (first: number, second: number) => ({ type, customProp1: first, customProp2: second });\n});\n\n// after\nconst add = createCustomAction(\n  'CUSTOM',\n  (first: number, second: number) => ({ customProp1: first, customProp2: second })\n);\n```\n\n5. `AsyncActionCreator` should be just renamed to `AsyncActionCreatorBuilder`.\n```ts\n// before\nimport { AsyncActionCreator } from \"typesafe-actions\"\n\n//after\nimport { AsyncActionCreatorBuilder } from \"typesafe-actions\"\n```\n\n### `v3.x.x` to `v4.x.x`\n\n**No breaking changes!**\n\n### `v2.x.x` to `v3.x.x`\n\nMinimal supported TypeScript `v3.1+`.\n\n### `v1.x.x` to `v2.x.x`\n\n**Breaking changes:**\n\n1. `createAction`\n- In `v2` we provide a `createActionDeprecated` function compatible with `v1` `createAction` to help with incremental migration.\n\n```ts\n// in v1 we created action-creator like this:\nconst getTodo = createAction('GET_TODO',\n  (id: string, meta: string) => ({\n    type: 'GET_TODO',\n    payload: id,\n    meta: meta,\n  })\n);\n\ngetTodo('some_id', 'some_meta'); // { type: 'GET_TODO', payload: 'some_id', meta: 'some_meta' }\n\n// in v2 we offer few different options - please choose your preference\nconst getTodoNoHelpers = (id: string, meta: string) => action('GET_TODO', id, meta);\n\nconst getTodoWithHelpers = createAction('GET_TODO', action => {\n  return (id: string, meta: string) => action(id, meta);\n});\n\nconst getTodoFSA = createStandardAction('GET_TODO')<string, string>();\n\nconst getTodoCustom = createStandardAction('GET_TODO').map(\n  ({ id, meta }: { id: string; meta: string; }) => ({\n    payload: id,\n    meta,\n  })\n);\n```\n\n[⇧ back to top](#table-of-contents)\n\n### Migrating from `redux-actions` to `typesafe-actions`\n\n- createAction(s)\n\n```ts\ncreateAction(type, payloadCreator, metaCreator) => createStandardAction(type)() || createStandardAction(type).map(payloadMetaCreator)\n\ncreateActions() => // COMING SOON!\n```\n\n- handleAction(s)\n\n```ts\nhandleAction(type, reducer, initialState) => createReducer(initialState).handleAction(type, reducer)\n\nhandleActions(reducerMap, initialState) => createReducer(initialState, reducerMap)\n```\n\n> TIP: If migrating from JS -> TS, you can swap out action-creators from `redux-actions` with action-creators from `typesafe-actions` in your `handleActions` handlers. This works because the action-creators from `typesafe-actions` provide the same `toString` method implementation used by `redux-actions` to match actions to the correct reducer.\n\n- combineActions\n\nNot needed because each function in the API accept single value or array of values for action types or action creators.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compatibility Notes\n\n**TypeScript support**\n\n- `5.X.X` - TypeScript v3.2+\n- `4.X.X` - TypeScript v3.2+\n- `3.X.X` - TypeScript v3.2+\n- `2.X.X` - TypeScript v2.9+\n- `1.X.X` - TypeScript v2.7+\n\n**Browser support**\n\nIt's compatible with all modern browsers.\n\nFor older browsers support (e.g. IE <= 11) and some mobile devices you need to provide the following polyfills:\n- [Object.assign](https://developer.mozilla.org/pl/docs/Web/JavaScript/Referencje/Obiekty/Object/assign#Polyfill)\n- [Array.prototype.includes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes)\n\n**Recommended polyfill for IE**\n\nTo provide the best compatibility please include a popular polyfill package in your application, such as `core-js` or `react-app-polyfill` for `create-react-app`.\nPlease check the `React` guidelines to learn how to do that: [LINK](https://reactjs.org/docs/javascript-environment-requirements.html)\nA polyfill fo IE11 is included in our `/codesandbox` application.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Recipes\n\n### Restrict Meta type in `action` creator\nUsing this recipe you can create an action creator with restricted Meta type with exact object shape.\n\n```tsx\nexport type MetaType = {\n  analytics?: {\n    eventName: string;\n  };\n};\n\nexport const actionWithRestrictedMeta = <T extends string, P>(\n  type: T,\n  payload: P,\n  meta: MetaType\n) => action(type, payload, meta);\n\nexport const validAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { eventName: 'success' } }); // OK!\n\nexport const invalidAction = (payload: string) =>\n  actionWithRestrictedMeta('type', payload, { analytics: { excessProp: 'no way!' } }); // Error\n// Object literal may only specify known properties, and 'excessProp' does not exist in type '{ eventName: string; }\n```\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Compare to others\n\nHere you can find out a detailed comparison of `typesafe-actions` to other solutions.\n\n### `redux-actions`\nLets compare the 3 most common variants of action-creators (with type only, with payload and with payload + meta)\n\nNote: tested with \"@types/redux-actions\": \"2.2.3\"\n\n**- with type only (no payload)**\n\n##### redux-actions\n```ts\nconst notify1 = createAction('NOTIFY');\n// resulting type:\n// () => {\n//   type: string;\n//   payload: void | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> with `redux-actions` you can notice the redundant nullable `payload` property and literal type of `type` property is lost (discrimination of union type would not be possible)\n\n##### typesafe-actions\n```ts\nconst notify1 = () => action('NOTIFY');\n// resulting type:\n// () => {\n//   type: \"NOTIFY\";\n// }\n```\n\n> with `typesafe-actions` there is no excess nullable types and no excess properties and the action \"type\" property is containing a literal type\n\n**- with payload**\n\n##### redux-actions\n```ts\nconst notify2 = createAction('NOTIFY',\n  (username: string, message?: string) => ({\n    message: `${username}: ${message || 'Empty!'}`,\n  })\n);\n// resulting type:\n// (t1: string) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   error: boolean | undefined;\n// }\n```\n\n> first the optional `message` parameter is lost, `username` semantic argument name is changed to some generic `t1`, `type` property is widened once again and `payload` is nullable because of broken inference\n\n##### typesafe-actions\n```ts\nconst notify2 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n// }\n```\n\n> `typesafe-actions` infer very precise resulting type, notice working optional parameters and semantic argument names are preserved which is really important for great intellisense experience\n\n**- with payload and meta**\n\n##### redux-actions\n```ts\nconst notify3 = createAction('NOTIFY',\n  (username: string, message?: string) => (\n    { message: `${username}: ${message || 'Empty!'}` }\n  ),\n  (username: string, message?: string) => (\n    { username, message }\n  )\n);\n// resulting type:\n// (...args: any[]) => {\n//   type: string;\n//   payload: { message: string; } | undefined;\n//   meta: { username: string; message: string | undefined; };\n//   error: boolean | undefined;\n// }\n```\n\n> this time we got a completely broken arguments arity with no type-safety because of `any` type with all the earlier issues\n\n##### typesafe-actions\n```ts\n/**\n * typesafe-actions\n */\nconst notify3 = (username: string, message?: string) => action(\n  'NOTIFY',\n  { message: `${username}: ${message || 'Empty!'}` },\n  { username, message },\n);\n// resulting type:\n// (username: string, message?: string | undefined) => {\n//   type: \"NOTIFY\";\n//   payload: { message: string; };\n//   meta: { username: string; message: string | undefined; };\n// }\n```\n\n> `typesafe-actions` never fail to `any` type, even with this advanced scenario all types are correct and provide complete type-safety and excellent developer experience \n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Motivation\n\nWhen I started to combine Redux with TypeScript, I was trying to use [redux-actions](https://redux-actions.js.org/) to reduce the maintainability cost and boilerplate of **action-creators**. Unfortunately, the results were intimidating: incorrect type signatures and broken type-inference cascading throughout the entire code-base [(click here for a detailed comparison)](#redux-actions).\n\nExisting solutions in the wild have been either **too verbose because of redundant type annotations** (hard to maintain) or **used classes** (hinders readability and requires using the **new** keyword 😱)\n\n**So I created `typesafe-actions` to address all of the above pain points.**\n\nThe core idea was to design an API that would mostly use the power of TypeScript **type-inference** 💪 to lift the \"maintainability burden\" of type annotations. In addition, I wanted to make it \"look and feel\" as close as possible to the idiomatic JavaScript ❤️ , so we don't have to write the redundant type annotations that which will create additional noise in your code.\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Contributing\n\nYou can help make this project better by contributing. If you're planning to contribute please make sure to check our contributing guide: [CONTRIBUTING.md](/CONTRIBUTING.md)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## Funding Issues\n\nYou can also help by funding issues.\nIssues like bug fixes or feature requests can be very quickly resolved when funded through the IssueHunt platform.\n\nI highly recommend to add a bounty to the issue that you're waiting for to increase priority and attract contributors willing to work on it.\n\n[![Let's fund issues in this repository](https://issuehunt.io/static/embed/issuehunt-button-v1.svg)](https://issuehunt.io/repos/110746954)\n\n[⇧ back to top](#table-of-contents)\n\n---\n\n## License\n\n[MIT License](/LICENSE)\n\nCopyright (c) 2017 Piotr Witek <piotrek.witek@gmail.com> (http://piotrwitek.github.io)\n","maintainers":[{"name":"piotrwitek","email":"piotrek.witek@gmail.com"}],"time":{"modified":"2022-05-22T13:28:41.356Z","created":"2017-12-24T22:49:21.308Z","0.0.1":"2017-12-24T22:49:21.308Z","1.0.0-rc.1":"2017-12-26T12:22:46.862Z","1.0.0":"2017-12-28T09:48:01.887Z","1.1.0":"2017-12-29T17:47:22.550Z","1.1.1":"2018-01-02T08:24:59.599Z","1.1.2":"2018-01-02T08:34:22.456Z","1.2.0-rc.0":"2018-03-26T10:07:18.433Z","1.2.0-rc.1":"2018-03-27T22:30:36.869Z","1.2.0-rc.2":"2018-03-28T08:01:29.137Z","1.2.0-rc.3":"2018-04-03T13:17:43.924Z","1.2.0-rc.4":"2018-04-03T23:49:32.063Z","2.0.0-0":"2018-04-04T18:46:13.473Z","2.0.0-1":"2018-04-05T19:07:55.260Z","1.1.3":"2018-05-09T07:56:40.764Z","2.0.0-test.0":"2018-05-11T13:35:19.978Z","2.0.0-rc.0":"2018-05-11T23:16:51.685Z","2.0.0-rc.1":"2018-05-13T10:46:07.662Z","2.0.0":"2018-05-15T09:23:44.842Z","2.0.1":"2018-05-17T08:20:28.043Z","2.0.2":"2018-05-17T10:55:03.630Z","2.0.3":"2018-05-17T11:08:00.582Z","2.0.4":"2018-05-27T12:18:27.572Z","2.1.0":"2018-12-26T15:44:52.126Z","2.1.1":"2018-12-26T15:54:19.450Z","2.2.0":"2018-12-30T14:09:48.513Z","3.0.0":"2018-12-30T14:16:30.620Z","3.1.0":"2019-02-15T21:43:53.415Z","3.1.1":"2019-02-24T23:32:49.569Z","3.2.0":"2019-02-24T23:53:13.701Z","3.2.1":"2019-02-25T09:19:50.295Z","3.3.0-rc":"2019-03-31T01:14:02.425Z","3.3.0":"2019-04-01T22:08:34.260Z","3.4.0":"2019-04-03T11:54:06.029Z","4.0.0":"2019-04-03T12:30:45.272Z","4.1.0":"2019-04-21T23:07:38.000Z","4.1.1":"2019-04-22T11:23:36.042Z","4.1.2":"2019-04-23T00:06:36.790Z","4.1.3":"2019-04-27T00:19:20.401Z","4.1.4":"2019-04-27T14:15:09.004Z","4.2.0":"2019-04-27T18:28:17.515Z","4.2.1":"2019-05-09T12:54:48.728Z","4.3.0":"2019-05-13T10:03:26.399Z","4.4.0":"2019-05-21T10:38:46.329Z","4.4.1":"2019-06-14T16:39:33.377Z","4.4.2":"2019-06-23T16:00:49.724Z","5.0.0-0":"2019-06-24T15:51:06.822Z","5.0.0-1":"2019-06-28T11:21:35.065Z","5.0.0-2":"2019-06-28T12:08:51.966Z","5.0.0-3":"2019-06-30T16:56:21.535Z","5.1.0-0":"2019-10-28T20:10:46.178Z","5.1.0-1":"2019-10-29T09:47:00.194Z","5.1.0":"2019-11-02T20:05:41.822Z"},"homepage":"https://github.com/piotrwitek/typesafe-actions","keywords":["typescript","typesafe","actions","action-creator","redux","flux","redux-actions","static-typing"],"repository":{"type":"git","url":"git+https://github.com/piotrwitek/typesafe-actions.git"},"author":{"name":"Piotr Witek","email":"piotrek.witek@gmail.com","url":"http://piotrwitek.github.io"},"bugs":{"url":"https://github.com/piotrwitek/typesafe-actions/issues"},"license":"MIT","readmeFilename":"README.md","users":{"sternelee":true,"piotrwitek":true}}