{"action":"created","issue":{"url":"https://api.github.com/repos/rackt/redux/issues/992","labels_url":"https://api.github.com/repos/rackt/redux/issues/992/labels{/name}","comments_url":"https://api.github.com/repos/rackt/redux/issues/992/comments","events_url":"https://api.github.com/repos/rackt/redux/issues/992/events","html_url":"https://github.com/rackt/redux/issues/992","id":114659720,"number":992,"title":"Support for typed actions (Typescript)","user":{"login":"nickknw","id":62827,"avatar_url":"https://avatars.githubusercontent.com/u/62827?v=3","gravatar_id":"","url":"https://api.github.com/users/nickknw","html_url":"https://github.com/nickknw","followers_url":"https://api.github.com/users/nickknw/followers","following_url":"https://api.github.com/users/nickknw/following{/other_user}","gists_url":"https://api.github.com/users/nickknw/gists{/gist_id}","starred_url":"https://api.github.com/users/nickknw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/nickknw/subscriptions","organizations_url":"https://api.github.com/users/nickknw/orgs","repos_url":"https://api.github.com/users/nickknw/repos","events_url":"https://api.github.com/users/nickknw/events{/privacy}","received_events_url":"https://api.github.com/users/nickknw/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/rackt/redux/labels/discussion","name":"discussion","color":"fbca04"}],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":18,"created_at":"2015-11-02T18:49:10Z","updated_at":"2015-12-22T11:08:19Z","closed_at":"2015-11-04T09:47:57Z","body":"Related to these two issues:\r\n - https://github.com/rackt/redux/issues/355\r\n - https://github.com/rackt/redux/issues/437\r\n\r\nHi Dan,\r\n\r\nThe company I am with is using Redux as well as Typescript, and we would like to add some additional compile-time guarantees to our actions. Currently this isn't possible because of the restriction that actions must be plain objects. You said that this is because 'record/replay and associated features won't work with an action class' and I get that those are valuable features and don't want to lose them. But I had code using Typescript classes that (when the redux devtools were enabled) could still record, cancel and replay actions just fine (using the code I posted in issue 355). \r\n\r\nWhen I remove the devtools I just get errors from that check that actions are plain objects and execution stop there. To me it seems like it is too strict, checking more than is really required. I would much rather have a check that requires that the actions are serializable. I know performance is a concern - IMO it shouldn't have to guarantee/prove they are serializable, just check that the action objects themselves say that they are, and then trust them. \r\n(Not sure why the check doesn't also fail when devtools are enabled - maybe you can shed light on that).\r\n\r\nI would really like to be able to leverage the advantages of both Typescript and Redux. Hope you can help me (and others using both of these tools) arrive at a solution.\r\n\r\nI also want to reiterate that (as much as I wish it were otherwise!) Typescript does not have discriminated unions, so solutions based on that approach will not work.\r\n\r\nThank you!"},"comment":{"url":"https://api.github.com/repos/rackt/redux/issues/comments/166583300","html_url":"https://github.com/rackt/redux/issues/992#issuecomment-166583300","issue_url":"https://api.github.com/repos/rackt/redux/issues/992","id":166583300,"user":{"login":"aikoven","id":857709,"avatar_url":"https://avatars.githubusercontent.com/u/857709?v=3","gravatar_id":"","url":"https://api.github.com/users/aikoven","html_url":"https://github.com/aikoven","followers_url":"https://api.github.com/users/aikoven/followers","following_url":"https://api.github.com/users/aikoven/following{/other_user}","gists_url":"https://api.github.com/users/aikoven/gists{/gist_id}","starred_url":"https://api.github.com/users/aikoven/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/aikoven/subscriptions","organizations_url":"https://api.github.com/users/aikoven/orgs","repos_url":"https://api.github.com/users/aikoven/repos","events_url":"https://api.github.com/users/aikoven/events{/privacy}","received_events_url":"https://api.github.com/users/aikoven/received_events","type":"User","site_admin":false},"created_at":"2015-12-22T11:08:19Z","updated_at":"2015-12-22T11:08:19Z","body":"I'm using [FSA](https://github.com/acdlite/flux-standard-action) and I found it very convenient to have generic `Action` interface with type parameter corresponding to `payload` type:\r\n\r\n```ts\r\ninterface Action<T>{\r\n  type: string;\r\n  payload: T;\r\n  error?: boolean;\r\n  meta?: any;\r\n}\r\n```\r\n\r\nThen I export payload type alongside action type using same name:\r\n\r\n```ts\r\nexport const ADD_TODO = 'ADD_TODO';\r\nexport type ADD_TODO = {text: string};\r\n```\r\n\r\nThis way when you import `ADD_TODO`, you actually import both action type and payload type:\r\n\r\n```ts\r\nimport {ADD_TODO} from './actions';\r\nimport {handleActions} from 'redux-actions';\r\n\r\nconst reducer = handleActions({\r\n  [ADD_TODO]: (state, action:Action<ADD_TODO>) => {\r\n    // enabled type checking for action.payload\r\n    // ...\r\n  }\r\n});\r\n```"}}