flow typing mismatch for function accepting a reducer












0















I want to create a function which does something to a reducer (it's not important what it is, just some transformation, similar to combineReducers). i have problem when i want to abstract the state for the reducer.
Here is the simplified reducer used for some component:



type someState = {
foo: number,
};
export const someSimpleReducer = (state: someState) => state;

type StateAbstract = {}; // this doesn't work
// type StateAbstract = any; // this works


and here the abstract transform function with abstracted state:



declare type SimpleReducer<S> = (state: S) => S;

export const transformReducer = (reducer: SimpleReducer<StateAbstract>) => ({
reducer,
});

transformReducer(someSimpleReducer);


i see the following flow error:




Flow: Cannot call transformReducer with someSimpleReducer bound to reducer because property foo is missing in StateAbstract [1] but exists in someState [2] in the first argument




If i use type StateAbstract = any then i don't see any error...
How can i write StateAbstract type so it's not any, but is an object?










share|improve this question



























    0















    I want to create a function which does something to a reducer (it's not important what it is, just some transformation, similar to combineReducers). i have problem when i want to abstract the state for the reducer.
    Here is the simplified reducer used for some component:



    type someState = {
    foo: number,
    };
    export const someSimpleReducer = (state: someState) => state;

    type StateAbstract = {}; // this doesn't work
    // type StateAbstract = any; // this works


    and here the abstract transform function with abstracted state:



    declare type SimpleReducer<S> = (state: S) => S;

    export const transformReducer = (reducer: SimpleReducer<StateAbstract>) => ({
    reducer,
    });

    transformReducer(someSimpleReducer);


    i see the following flow error:




    Flow: Cannot call transformReducer with someSimpleReducer bound to reducer because property foo is missing in StateAbstract [1] but exists in someState [2] in the first argument




    If i use type StateAbstract = any then i don't see any error...
    How can i write StateAbstract type so it's not any, but is an object?










    share|improve this question

























      0












      0








      0








      I want to create a function which does something to a reducer (it's not important what it is, just some transformation, similar to combineReducers). i have problem when i want to abstract the state for the reducer.
      Here is the simplified reducer used for some component:



      type someState = {
      foo: number,
      };
      export const someSimpleReducer = (state: someState) => state;

      type StateAbstract = {}; // this doesn't work
      // type StateAbstract = any; // this works


      and here the abstract transform function with abstracted state:



      declare type SimpleReducer<S> = (state: S) => S;

      export const transformReducer = (reducer: SimpleReducer<StateAbstract>) => ({
      reducer,
      });

      transformReducer(someSimpleReducer);


      i see the following flow error:




      Flow: Cannot call transformReducer with someSimpleReducer bound to reducer because property foo is missing in StateAbstract [1] but exists in someState [2] in the first argument




      If i use type StateAbstract = any then i don't see any error...
      How can i write StateAbstract type so it's not any, but is an object?










      share|improve this question














      I want to create a function which does something to a reducer (it's not important what it is, just some transformation, similar to combineReducers). i have problem when i want to abstract the state for the reducer.
      Here is the simplified reducer used for some component:



      type someState = {
      foo: number,
      };
      export const someSimpleReducer = (state: someState) => state;

      type StateAbstract = {}; // this doesn't work
      // type StateAbstract = any; // this works


      and here the abstract transform function with abstracted state:



      declare type SimpleReducer<S> = (state: S) => S;

      export const transformReducer = (reducer: SimpleReducer<StateAbstract>) => ({
      reducer,
      });

      transformReducer(someSimpleReducer);


      i see the following flow error:




      Flow: Cannot call transformReducer with someSimpleReducer bound to reducer because property foo is missing in StateAbstract [1] but exists in someState [2] in the first argument




      If i use type StateAbstract = any then i don't see any error...
      How can i write StateAbstract type so it's not any, but is an object?







      redux flowtype






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 25 '18 at 14:47









      Jacek KolasaJacek Kolasa

      531412




      531412
























          1 Answer
          1






          active

          oldest

          votes


















          1














          declare type SimpleReducer<S> = (state: S) => S;


          declares a type SimpleReducer which is a function that takes an S and returns an S.



          transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.



          transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:



          export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})


          Here it is on Try Flow.






          share|improve this answer
























          • Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

            – Jacek Kolasa
            Nov 25 '18 at 15:42













          • updated Try Flow

            – Jacek Kolasa
            Nov 25 '18 at 15:43











          • If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

            – Stefan
            Nov 25 '18 at 15:52













          • That makes perfect sense, thanks!

            – Jacek Kolasa
            Nov 25 '18 at 16:06






          • 1





            Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

            – Stefan
            Nov 25 '18 at 16:06











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53468676%2fflow-typing-mismatch-for-function-accepting-a-reducer%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          declare type SimpleReducer<S> = (state: S) => S;


          declares a type SimpleReducer which is a function that takes an S and returns an S.



          transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.



          transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:



          export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})


          Here it is on Try Flow.






          share|improve this answer
























          • Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

            – Jacek Kolasa
            Nov 25 '18 at 15:42













          • updated Try Flow

            – Jacek Kolasa
            Nov 25 '18 at 15:43











          • If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

            – Stefan
            Nov 25 '18 at 15:52













          • That makes perfect sense, thanks!

            – Jacek Kolasa
            Nov 25 '18 at 16:06






          • 1





            Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

            – Stefan
            Nov 25 '18 at 16:06
















          1














          declare type SimpleReducer<S> = (state: S) => S;


          declares a type SimpleReducer which is a function that takes an S and returns an S.



          transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.



          transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:



          export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})


          Here it is on Try Flow.






          share|improve this answer
























          • Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

            – Jacek Kolasa
            Nov 25 '18 at 15:42













          • updated Try Flow

            – Jacek Kolasa
            Nov 25 '18 at 15:43











          • If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

            – Stefan
            Nov 25 '18 at 15:52













          • That makes perfect sense, thanks!

            – Jacek Kolasa
            Nov 25 '18 at 16:06






          • 1





            Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

            – Stefan
            Nov 25 '18 at 16:06














          1












          1








          1







          declare type SimpleReducer<S> = (state: S) => S;


          declares a type SimpleReducer which is a function that takes an S and returns an S.



          transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.



          transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:



          export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})


          Here it is on Try Flow.






          share|improve this answer













          declare type SimpleReducer<S> = (state: S) => S;


          declares a type SimpleReducer which is a function that takes an S and returns an S.



          transformReducer is a function that takes a SimpleReducer<StateAbstract> i.e. a function that takes a StateAbstract and returns a StateAbstract.



          transformReducer shouldn't care about what type that reducer function takes and returns. Instead of using a concrete type use a generic:



          export const transformReducer = <S>(reducer: SimpleReducer<S>) => ({reducer})


          Here it is on Try Flow.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 25 '18 at 15:24









          StefanStefan

          60028




          60028













          • Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

            – Jacek Kolasa
            Nov 25 '18 at 15:42













          • updated Try Flow

            – Jacek Kolasa
            Nov 25 '18 at 15:43











          • If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

            – Stefan
            Nov 25 '18 at 15:52













          • That makes perfect sense, thanks!

            – Jacek Kolasa
            Nov 25 '18 at 16:06






          • 1





            Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

            – Stefan
            Nov 25 '18 at 16:06



















          • Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

            – Jacek Kolasa
            Nov 25 '18 at 15:42













          • updated Try Flow

            – Jacek Kolasa
            Nov 25 '18 at 15:43











          • If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

            – Stefan
            Nov 25 '18 at 15:52













          • That makes perfect sense, thanks!

            – Jacek Kolasa
            Nov 25 '18 at 16:06






          • 1





            Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

            – Stefan
            Nov 25 '18 at 16:06

















          Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

          – Jacek Kolasa
          Nov 25 '18 at 15:42







          Thanks! but what if i want to make sure transformReducer doesn't accept any wrong functions? Reducer should accept state as an object, not string. So i want to throw error on this situation? const improperReducer = (state: string) => state; transformReducer(improperReducer); or maybe i am just overdiligent?

          – Jacek Kolasa
          Nov 25 '18 at 15:42















          updated Try Flow

          – Jacek Kolasa
          Nov 25 '18 at 15:43





          updated Try Flow

          – Jacek Kolasa
          Nov 25 '18 at 15:43













          If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

          – Stefan
          Nov 25 '18 at 15:52







          If you want to only allow reducers that take objects, then SimpleReducer should be declared like SimpleReducer = (state: Object) => Object. And transformReducer is simply transformReducer = (reducer: SimpleReducer) => ({reducer}). Try Flow Example

          – Stefan
          Nov 25 '18 at 15:52















          That makes perfect sense, thanks!

          – Jacek Kolasa
          Nov 25 '18 at 16:06





          That makes perfect sense, thanks!

          – Jacek Kolasa
          Nov 25 '18 at 16:06




          1




          1





          Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

          – Stefan
          Nov 25 '18 at 16:06





          Oh and in case you want to keep SimpleReducer generic then you can specify the concrete type in transformReducer like so: transformReducer = (reducer: SimpleReducer<Object>) => ({ reducer })

          – Stefan
          Nov 25 '18 at 16:06


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53468676%2fflow-typing-mismatch-for-function-accepting-a-reducer%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

          Calculate evaluation metrics using cross_val_predict sklearn

          Insert data from modal to MySQL (multiple modal on website)