Skip to content

Error in types for middleware (typescript 2.4.1) #2481

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
artem-malko opened this issue Jun 29, 2017 · 19 comments
Closed

Error in types for middleware (typescript 2.4.1) #2481

artem-malko opened this issue Jun 29, 2017 · 19 comments

Comments

@artem-malko
Copy link

artem-malko commented Jun 29, 2017

It is a bug

I have this simple middleware:

import { Middleware, Store, Dispatch, Action } from 'redux';
import { AppState } from 'types/appState';

export default function createSimpleMiddleware(): Middleware {
  return (store: Store<AppState>) => (next: Dispatch<AppState>) => (action: Action): Action => {
    return next(action);
  };
}

It is useless, but there is a problem) This code works with typescript version 2.3.x and below. But in typescript 2.4 there is an Error.

What is the current behavior?
In typescript I have this Error:

Types of parameters 'store' and 'api' are incompatible.
    Type 'MiddlewareAPI<S>' is not assignable to type 'Store<AppState>'.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://jsfiddle.net or similar.

You can find demo code at the top of current issue.

What is the expected behavior?

I expect, that there won't be any errors.

Which versions of Redux, and which browser and OS are affected by this issue? Did this work in previous versions of Redux?

Typescript: 2.4.1
Redux: 3.7.1
NodeJS: 6.9.1
OS: MacOS

@timdorr
Copy link
Member

timdorr commented Jun 29, 2017

Just merged this in yesterday: #2467

@timdorr timdorr closed this as completed Jun 29, 2017
@artem-malko
Copy link
Author

artem-malko commented Jun 29, 2017

@timdorr but my bug is not about reducers. It is about middleware) Fix from #2467 fixes many problems, yes, but not for middleware.

@timdorr
Copy link
Member

timdorr commented Jun 29, 2017

Sorry, this is all sort of a mess and I'm not well-versed in TS. Is #2483 related?

@morlay
Copy link

morlay commented Jun 30, 2017

@artem-malko could you test this pr #2479 with [email protected], it works well in my project.

@artem-malko
Copy link
Author

@timdorr I understand. No #2483 is about reducers too, not about middleware)
@morlay no, my example is not working(

Types of parameters 'store' and 'api' are incompatible.
    Type 'MiddlewareAPI<S>' is not assignable to type 'Store<AppState>'.

And if I change code to:

import { Middleware, MiddlewareAPI, Dispatch, Action } from 'redux';
import { AppState } from 'types/appState';

export default function createSimpleMiddleware(): Middleware {
  return (store: MiddlewareAPI<AppState>) => (next: Dispatch<AppState>) => (action: Action): Action => {
    return next(action);
  };
}

It has errors too:

ypes of parameters 'store' and 'api' are incompatible.
    Type 'MiddlewareAPI<S>' is not assignable to type 'MiddlewareAPI<AppState>'.
      Type 'S' is not assignable to type 'AppState'.

@artem-malko
Copy link
Author

@timdorr @morlay hey, any updates?)

@morlay
Copy link

morlay commented Jul 6, 2017

@artem-malko after [email protected] change the generics check,

Middleware should change the position ofS too.

export interface Middleware<S> {
  (api: MiddlewareAPI<S>): (next: Dispatch<S>) => Dispatch<S>;
}

@aikoven
Copy link
Collaborator

aikoven commented Jul 10, 2017

Middleware should change the position of S too.

Most middlewares can work regardless of state type, so in these cases, it's not a type parameter of Middleware, but of its call signature.

As you can see in typings for Store enhancers, there are two versions: one for fixed state type, and one generic. I think we should follow the same approach for middleware.

@artem-malko
Copy link
Author

@morlay @aikoven yes, I have just copied all types for redux and made as @morlay said. And it works.

@Llorx
Copy link

Llorx commented Jul 19, 2017

I have the same problem and don't really know how to overcome this without forcing an <any> and then cast back to <State>. That's a dirty cheat and I don't like it.

My function is as small as this: http://i.imgur.com/qcxGmoj.gifv

What should I do to fix this? I don't understand half of the messages above, sorry :-/

My typescript version is 2.5.0-dev.20170712. The same happens with 2.4.1

I have reducers correctly typed, as you can see createStore returns my State type.

@aikoven
Copy link
Collaborator

aikoven commented Jul 20, 2017

@Llorx What error do you get?

@Llorx
Copy link

Llorx commented Jul 20, 2017

@aikoven Ok, this is weird. I had a method that accepted a State parameter and when I do store.getState() it break saying that S cannot be converted to State, so, meanwhile, I foced an any.

Now I removed the any cast to see the error again and it works...: http://i.imgur.com/8ikVGgM.gifv

I guess that I had a type problem elsewhere that affected here. I thought that the IDE should show MiddlewareAPI<State> instead of MiddlewareAPI<S> to tell that detected the type correctly, that's why I showed the first gif, but seems that it doesn't.

@tbo
Copy link

tbo commented Jul 21, 2017

I can reproduce the error:

Types of parameters 'store' and 'api' are incompatible.
    Type 'MiddlewareAPI<S>' is not assignable to type 'MiddlewareAPI<IState>'.
      Type 'S' is not assignable to type 'IState'.

I tried to change the typings for Middleware as @morlay suggested, but it clashed with reduxThunk.

TypeScript: 2.4.2
Redux: 3.7.2
NodeJS: 8.1.4
OS: MacOS

@tbo
Copy link

tbo commented Jul 24, 2017

This is my workaround for now:

declare module 'redux' {
  export interface Middleware<T=any> {
    <S>(api: MiddlewareAPI<S>): (next: Dispatch<S>) => Dispatch<S>;
    (api: MiddlewareAPI<T>): (next: Dispatch<T>) => Dispatch<T>;
  }
}

@timdorr Shouldn't we reopen this until it is fixed?

@davidka
Copy link

davidka commented Jul 26, 2017

Please reopen, this is not fixed yet. I still have the same error too

TypeScript: 2.4.2
Redux: 3.7.2
NodeJS: 7.7.3
OS: MacOS

@timdorr timdorr reopened this Jul 26, 2017
@timdorr
Copy link
Member

timdorr commented Jul 26, 2017

Can someone work up a fix PR?

@timdorr
Copy link
Member

timdorr commented Oct 6, 2017

Should be fixed by #2563

@timdorr timdorr closed this as completed Oct 6, 2017
@macdonaldr93
Copy link

Is it possible to add an example of what a valid middleware would look like with typescript? Even after following this thread, I'm unsure how to update my middleware so that it compiles correctly and types are satisfied.

@aikoven
Copy link
Collaborator

aikoven commented Feb 19, 2018

@macdonaldr93 See the tests for Middleware types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants