piotrwitek / typesafe-actions

Typesafe utilities for "action-creators" in Redux / Flux Architecture
https://codesandbox.io/s/github/piotrwitek/typesafe-actions/tree/master/codesandbox
MIT License
2.41k stars 99 forks source link

v5.1 has more breaking changes than are documented in the release #209

Closed C-Higgins closed 2 years ago

C-Higgins commented 4 years ago

I just upgraded from 4.4.2 to 5.1.0, following the migration guide. I replaced the methods with their deprecated counterparts, and I was only using createStandardAction everywhere so it was simple. However the types were still broken after that. There were type is 'unknown' errors everywhere in the redux code, which I think stemmed back to the createReducer or the combineReducers not emitting the right type. RootState was suddenly full of unknowns as well. I don't have a reproduction for this, but I think more must be breaking than just the action creator functions.

piotrwitek commented 4 years ago

Hey, I'll need a reproduction case or it's impossible to do anything about your issues.

mavajee commented 4 years ago

@piotrwitek code from examples for createAsyncAction

image image image

C-Higgins commented 4 years ago

I noticed that if I remove this type override in v4, I get the exact same error as I do when upgrading to v5. Perhaps this is not the correct way to override in v5.

My override:

declare module 'typesafe-actions' {
  interface Types {
    RootAction: RootAction; //this is my imported RA
  }
}
piotrwitek commented 4 years ago

@mavajee what you're showing is not possible because there are unit tests and it's working correctly. Please provide a full reproduction case in a new issue if you want me to look at it.

@C-Higgins the override is correct, check the similar issue here confirmed it's working: https://github.com/piotrwitek/typesafe-actions/issues/210#issuecomment-554508758

tstelzer commented 4 years ago

@C-Higgins: I had the same error. Problem was me not properly following the migration guide, and failing to do

import { deprecated } from "typesafe-actions";
const { createAction, createStandardAction } = deprecated;

everywhere I was still using the old action creators. That lead to my root-action to be incorrectly typed, which in turn caused my root-reducer to be incorrectly typed.

C-Higgins commented 4 years ago

Found the problem. At some point in the past, the handleAction took a getType call as the first parameter, like so:

createReducer(initialState as Readonly<typeof initialState>).handleAction(
  getType(someAction),
  (state, action) => ({}),
);

This works properly in 4.4.2. In 5.1.0, you must remove the getType function and just pass the action.

piotrwitek commented 4 years ago

@C-Higgins thanks a lot for investigating this issue. I think you're right, the reason here is that handleAction was supporting string constants. In v5 you can still do it but it has a separate handler called handleType.

I'll add it to the breaking changes, thanks a lot for help!

timosnel commented 4 years ago

@piotrwitek the issue mentioned by @mavajee happens when the TypeScript setting 'strictNullChecks' is set to false. I just ran into the same problem.

We're currently in the process of migrating to stricter TS settings, but in case someone else runs into this, at least they know the cause.

This is what the type signature looks like with strictNullChecks turned off: afbeelding

feimosi commented 4 years ago

I can confirm the same happens in our project (strictNullChecks set to false). It expects the payload and meta parameters.

This action creator

const fetchUsers = createAsyncAction(
  'Fetch users / Loading',
  'Fetch users / Success',
  'Fetch users / Failure',
)<
  undefined,
  { users: number[] },
  { error: Error }
>();

is typed as:

const fetchUsers.request: (payload: unknown, meta: unknown) => 
    PayloadMetaAction<"Fetch users", unknown, unknown>

and fails with:

error TS2554: Expected 2 arguments, but got 0.
120   yield put(fetchUsers());
hapablap21 commented 4 years ago

It looks like if you replace undefined in the createAsyncAction generic parameters with [undefined, undefined], it behaves correctly. I'm not sure if that's expected behavior, but it's suboptimal for action creators that don't need a parameter.

alexkazantsev commented 4 years ago

@hapablap21 thanks! you saved my day :)