Could typeOf narrowing work without explicit generics in TypeScript 2.8?
See original GitHub issueWhile #385 did provide a solution for maintaining action type safety through ofType<Action, ActionType>(action)
filtering, it’s a bit inconvenient to use and I’m wondering if predefined conditional types in TS 2.8 (https://github.com/Microsoft/TypeScript/pull/21847) would make it possible to narrow down the type from one big union type, without passing in the explicit type.
I’d imagine most people want to infer action types from action creators and not write explicit type definitions, because of how verbose it gets with lots of actions. This is pretty viable now (see https://medium.com/@martin_hotell/improved-redux-type-safety-with-typescript-2-8-2c11a8062575 for example).
At least from the reducer’s point of view, it’s fine to have one big action union type, which can be derived from all action creators with ReturnType<typeof actionCreator>
. Narrowing works just as you’d expect, just matching type with string enum or constant.
I kinda expected it to work the same way in my epics as well, but as the troubleshooting manual says, I need to pass in the exact action type to the generic typeOf for the narrowing to work.
For now I’m doing something like this
// src/state/example/example.epics.ts
import { Epic, ofType, combineEpics } from 'redux-observable'
import { switchMap } from 'rxjs/operators/switchMap'
import { ActionAny, RootState } from '../index'
import * as actions from './example.actions'
const exampleFetchAllEpic: Epic<ActionAny, RootState> = (action$, store) =>
action$.pipe(
ofType<ActionAny, ReturnType<typeof actions.exampleActionFetchAll>>(
actions.ExampleActionType.FETCH_ALL
),
switchMap(action => {
console.log(action.payload.foo)
})
)
export const epics = combineEpics(
exampleFetchAllEpic
)
Now I don’t quite understand why the narrowing requires this pattern and it’s not a huge issue, so sorry if it’s simply not viable, but I feel like the action type should be implicit since ActionAny is already union of all the return types.
Also TS 2.8 isn’t stable release yet so I don’t expect it to be supported either, but just wanted to bring this up in advance.
Edit: After going through other related issues, I realised the conditional types in 2.8 may not solve the issue here. Still, it feels redundant to declare the exact action type and check the type field, so I’m curious to what needs to happen for the TS compiler to understand the narrowing, or if anyone has workarounds for it.
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (2 by maintainers)
I was playing around with TS 2.8 and it’s actually possible to write
ofType
in a way that automatically narrows discriminated unionAction
types for a single Action (which I think is a pretty common use-case). Here’s the basic implementation:And then the definition of
ofType
would change to this:It does work (#459) but it’s a breaking change and it requires TS 2.8 so I don’t think it’ll get merged until more of the ecosystem transitioned to the new version.