Guide to incorporating a default generic type: implementing createReducer with the Flow type system

Click here for a useful createReducer() function. How would you annotate it using Flow?

Here is an example:

// @flow
import type { TAction as TActionDefault } from '../actions/types';

type THandlers<TState, TAction> = {
  [key: string]: (state: TState, action: TAction) => any
}

type TReducer<TState, TAction> = (state: TState, action: TAction) => TState


export default function createReducer<TState, TAction>(
  initialState: TState,
  handlers: THandlers<TState, TAction>
): TReducer<TState, TAction> {
  return function reducer(state: TState = initialState, action: TAction): TState {
    if (handlers[action.type]) {
      return handlers[action.type](state, action)
    } else {
      return state
    }
  }
}

However, there is an issue:

Cannot access `action.type` because the property `type` is missing in `TAction` [1]. (References: [1])

And Flow does not allow specifying a default type value for TAction.

How would you handle this situation and similar cases?

Answer №1

With Flow, you can easily set a default value for the generic parameter.

createReducer<TState, TAction = DefaultAction>

This code snippet was confirmed to be functional in June 2019. For more information, visit https://github.com/facebook/flow/issues/6875

Answer №2

The issue arose in this part

createReducer<TState, TAction>

I attempted to include a default value for the generic parameter like so

createReducer<TState, TAction = TActionDefault>

However, this is the correct syntax.

createReducer<TState, TAction: TActionDefault>

As a result, the final code appears as follows

// @flow
import type { TAction as TActionDefault } from '../actions/types';

type THandlers<TState, TAction> = {
  [key: string]: (state: TState, action: TAction) => TState
}

type TReducer<TState, TAction = any> = (state: TState, action: TAction) => TState

export default function createReducer<TState, TAction: TActionDefault<any>>(
  initialState: TState,
  handlers: THandlers<TState, TAction>
): TReducer<TState, TAction> {
  return function reducer(state: TState = initialState, action: TAction): TState {
    if (handlers[action.type]) {
      return handlers[action.type](state, action);
    }
    return state;
  };
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilize AJAX and JavaScript to retrieve file information and facilitate file downloads

I have developed a script that intercepts Captcha form submissions. Typically, when the form is submitted, a file will be downloaded (such as exe or zip) in the usual way where it appears at the bottom of the Chrome browser and gets stored in the "download ...

A guide on incorporating and utilizing third-party Cordova plugins in Ionic 5

Attempting to implement this plugin in my Ionic 5 application: https://www.npmjs.com/package/cordova-plugin-k-nfc-acr122u I have added the plugin using cordova plugin add cordova-plugin-k-nfc-acr122u but I am unsure of how to use it. The plugin declares: ...

Having trouble getting jQuery Ajax data to work properly on the same PHP page?

I am working with a file called 22.php where both the form and PHP script are located. Issues: https://i.sstatic.net/3vG5N.jpg https://i.sstatic.net/5KXz6.jpg 1) After submitting, the result is displayed below. However, it duplicates the form. 2) Ente ...

Unable to fetch JSON data using JQuery AJAX

I am having trouble connecting to a Web service. I have tried various options and changed parameters, but I'm not sure where to look for the issue. This is my first time using AJAX for connection, and I've attempted to connect through different c ...

Three.js: How to Make a Camera Circle a Sphere?

How can we use Three.js and JavaScript/ WebGL to create a camera that orbits a sphere at a fixed height, with a fixed forward speed, and maintaining a fixed orientation in relation to the sphere? The user should only be able to steer the camera left and ri ...

For handling the onSubmit event, utilize both axios and axios-mock-adapter

I am attempting to utilize both axios and axios-mock-adapter in a single location to consolidate multiple mocks, then export the axios instance for use elsewhere: axios.js import axios from 'axios'; let api = axios.create({ baseURL: 'h ...

angular2 : problem encountered with communication to rest api

Transitioning from PHP to Angular2 has been quite challenging for me, especially when trying to use a real rest API like "Tour of Heroes". I initially thought it would be simple... Currently, I have set up a functional API with Express: curl -XGET http:/ ...

Executing functions in order [Node JS]

There are 2 functions in my code, where one function runs inside the other and the second one utilizes the output of the first function (list). I am looking to run these functions sequentially. Can anyone provide assistance? gm_scrape.search_link(request ...

Leveraging the jQuery UI keyboard plugin for iOS and Android devices

Recently, I've been tackling the challenge of integrating the jQuery UI Virtual keyboard plugin for ios/android web sites that are exclusively accessed through a webview. One issue that has come up is how to prevent the default keyboards on IOS/Androi ...

Concocting your custom blob in Angular 2 from input may lead to data corruption

For educational purposes, I am looking to utilize the html input tag in order to select a jpeg image, extract the File Object, read it with fileReader, and use the retrieved image string (base64) to generate a new blob/file. The service successfully uploa ...

Trouble arises with AJAX due to DOM traversal errors

I am trying to set up a system for liking and disliking with a counter. However, I am facing issues with my AJAX call, specifically when attempting to change the HTML of selected elements in the view after sending values to the DB. The element in question ...

Is it possible to replicate keystrokes using Selenium in a CodeMirror text editor?

There are numerous illustrations available that demonstrate how to input text using selenium by utilizing the following code: driver.execute_script('cm.setValue("text")'); While this method works, it does not align with the standard practices o ...

What is the process for incorporating TypeScript typings into a snippet of jQuery code designed for a Bootstrap multilevel dropdown menu?

I'm exploring Angular for the first time and trying to create a multi-level dropdown using Bootstrap. I came across this article which contains some JavaScript code snippets that I am struggling with. I need help converting this code into TypeScript, ...

Ways to apply Angular ng-options outside of a select element besides traditional use?

According to the official documentation, ng-options can be used on any element, not limited to just the select tag. This flexibility allows for enhanced customization of the selection UI, such as displaying thumbnail images or additional information beyond ...

Identifying Cross-Origin (CORS) Error from Other Errors in JavaScript's XMLHttpRequest()

I am currently working on detecting when an XMLHttpRequest() fails due to a Cross Origin Error rather than a bad request. Take, for example: ajaxObj=new XMLHttpRequest() ajaxObj.open("GET", url, true); ajaxObj.send(null); Let's consider ...

Using AngularJS to prefill a HTML5 date input field with a default value

Is there a way to bind the default value generated in moment to both the date and time input fields? I have tried using ng-model and directly binding it to the value attributes, but without success. Any suggestions on how to make this work? Edit: Addition ...

What is the best way to make useEffect trigger on an array's sorting?

Currently, I am working with a data object structured like this: const example = [{medicineName: "Some name", medicineId: 1}, {medicineName : "Some other name", medicineId : 2} ] const [filteredMedicineList, setFilteredMedicineList] = useState([]); ...

Creating arrays in JavaScript or jQuery is as simple as it is in Python

newArray = [arr[p2][item] for (item in subarray)] Is there a way to achieve a similar shortcut in JavaScript or with the help of jQuery without explicitly looping and adding elements to an array? This would allow me to perform additional calculations usi ...

The controller method in Laravel is not being triggered by AJAX

In my blade layout file, I have some code that is included in my view multiple times using the @include.layout("blade file link") syntax. When a button is pressed, I want to call a controller function. This works fine without AJAX, but when AJAX is added, ...

Prop type failure: The `actions` prop is specified as mandatory in the `Testing` component, however, its value is currently undefined

I am working on a project that involves creating a login form using React and Redux. Here's a snippet of my app.js: import React from 'react'; import { render } from 'react-dom'; import Input from 'react-toolbox/lib/input&apo ...