{"action":"created","issue":{"url":"https://api.github.com/repos/redux-observable/redux-observable/issues/459","repository_url":"https://api.github.com/repos/redux-observable/redux-observable","labels_url":"https://api.github.com/repos/redux-observable/redux-observable/issues/459/labels{/name}","comments_url":"https://api.github.com/repos/redux-observable/redux-observable/issues/459/comments","events_url":"https://api.github.com/repos/redux-observable/redux-observable/issues/459/events","html_url":"https://github.com/redux-observable/redux-observable/pull/459","id":309149149,"node_id":"MDExOlB1bGxSZXF1ZXN0MTc3ODc3MTM4","number":459,"title":"Automatically narrow Action type in the ofType operator","user":{"login":"Gustorn","id":2189776,"node_id":"MDQ6VXNlcjIxODk3NzY=","avatar_url":"https://avatars1.githubusercontent.com/u/2189776?v=4","gravatar_id":"","url":"https://api.github.com/users/Gustorn","html_url":"https://github.com/Gustorn","followers_url":"https://api.github.com/users/Gustorn/followers","following_url":"https://api.github.com/users/Gustorn/following{/other_user}","gists_url":"https://api.github.com/users/Gustorn/gists{/gist_id}","starred_url":"https://api.github.com/users/Gustorn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Gustorn/subscriptions","organizations_url":"https://api.github.com/users/Gustorn/orgs","repos_url":"https://api.github.com/users/Gustorn/repos","events_url":"https://api.github.com/users/Gustorn/events{/privacy}","received_events_url":"https://api.github.com/users/Gustorn/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2018-03-27T21:59:31Z","updated_at":"2018-09-06T17:49:55Z","closed_at":null,"author_association":"NONE","pull_request":{"url":"https://api.github.com/repos/redux-observable/redux-observable/pulls/459","html_url":"https://github.com/redux-observable/redux-observable/pull/459","diff_url":"https://github.com/redux-observable/redux-observable/pull/459.diff","patch_url":"https://github.com/redux-observable/redux-observable/pull/459.patch"},"body":"BREAKING CHANGE: The TypeScript definitions now require TS 2.8+ and `ofType` operations in existing codebases will also stop working (they will fail with a compilation error in case they specified the action type as a generic parameter)\r\n\r\nWith the new conditional types in TS 2.8 it's now possible to correctly narrow action types in `ofType` (and there are even some nice standard library types to do so).\r\n\r\nThe only downside of the current implementation is that the lettable version of the operator cannot restrict the the key types to the types used by the actions themselves. Compare the definition of the chained version:\r\n\r\n```ts\r\nofType<K extends T['type']>(...)\r\n```\r\n\r\nWith the lettable one:\r\n\r\n```ts\r\nfunction ofType<T extends Action, K extends string>(...)\r\n```\r\n\r\nUnfortunately in the second case, changing the constraint to `K extends T['type']` breaks the action type inference needed for the automatic narrowing.\r\n\r\nAs far as I can see this is unavoidable but it doesn't really cause any problems except for slightly worse error messages. If you pass a type that is not compatible with the action:\r\n\r\n1. In the chaining case: you get an error telling you that the parameter is not assignable to the action type\r\n2. In the lettable case: the narrowed action type will be `never` so you essentially won't be able to use it for anything useful\r\n\r\n\r\n\r\n- [x] I have read the [Contributor Guide](https://github.com/redux-observable/redux-observable/blob/master/CONTRIBUTING.md)\r\n- [x] My commit messages are in [conventional-changelog-standard](https://github.com/redux-observable/redux-observable/blob/master/CONTRIBUTING.md#sending-a-pull-request) format.\r\n"},"comment":{"url":"https://api.github.com/repos/redux-observable/redux-observable/issues/comments/419183556","html_url":"https://github.com/redux-observable/redux-observable/pull/459#issuecomment-419183556","issue_url":"https://api.github.com/repos/redux-observable/redux-observable/issues/459","id":419183556,"node_id":"MDEyOklzc3VlQ29tbWVudDQxOTE4MzU1Ng==","user":{"login":"jayphelps","id":762949,"node_id":"MDQ6VXNlcjc2Mjk0OQ==","avatar_url":"https://avatars1.githubusercontent.com/u/762949?v=4","gravatar_id":"","url":"https://api.github.com/users/jayphelps","html_url":"https://github.com/jayphelps","followers_url":"https://api.github.com/users/jayphelps/followers","following_url":"https://api.github.com/users/jayphelps/following{/other_user}","gists_url":"https://api.github.com/users/jayphelps/gists{/gist_id}","starred_url":"https://api.github.com/users/jayphelps/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jayphelps/subscriptions","organizations_url":"https://api.github.com/users/jayphelps/orgs","repos_url":"https://api.github.com/users/jayphelps/repos","events_url":"https://api.github.com/users/jayphelps/events{/privacy}","received_events_url":"https://api.github.com/users/jayphelps/received_events","type":"User","site_admin":false},"created_at":"2018-09-06T17:49:55Z","updated_at":"2018-09-06T17:49:55Z","author_association":"MEMBER","body":"@madshargreave ultimately I'm worried about the error messages produced by the lettable version of `ofType` with this solution.\r\n\r\n> The only downside of the current implementation is that the lettable version of the operator cannot restrict the the key types to the types used by the actions themselves.\r\n\r\n> In the lettable case: the narrowed action type will be never so you essentially won't be able to use it for anything useful\r\n\r\nI was playing with these changes and even though I had read this before, I forgot and was pretty confused when I saw `The type 'never' has no property 'payload' and no string index signature`. Made worse is that this error is not when you try and filter your actions with an unknown action type, but rather when you later try to use that filtered action.\r\n\r\n```ts\r\nconst epic: Epic<{ type: 'FIRST', payload: string }> = action$ =>\r\n  action$.pipe(\r\n    ofType('DOES_NOT_EXIST'), // no error here, even though ideally it would be\r\n    map(({ payload }) => ({   // error is here, not above\r\n      type: 'SECOND',\r\n      payload\r\n    }))\r\n  );\r\n```\r\n\r\nI've played around with various attempts, and also kept an eye on what [ngrx/effects is thinking about doing](https://github.com/ngrx/platform/pull/1183) but they too have the same issue.\r\n\r\nI'm not yet convinced this is worth the confusion it creates, but I do welcome anyone who has thoughts on why my fears are unfounded?"}}
{"actor":{"display_login":"jayphelps"}}