Precise object mapping with Redux and Typescript

In my redux slice, I have defined a MyState interface with the following structure:

interface MyState {
  key1: string,
  key2: boolean,
  key3: number,
}

There is an action named set which has this implementation:

set: (state: MyState, action: PayloadAction<{key: keyof MyState, value: any}>) => {
  const { key, value } = action.payload;
  state[key] = value;
},

I aim to strictly validate the keys and values passed in the set() action based on their types. For example:

set('key1', 1); // -> error: key1 must be a string
set('key1', 'my string value'); // -> no error

set('key2', boolean); // -> no error
set('key2', 'my string value'); // -> error: must be a boolean

Although I came across this function signature definition, I am unsure how to incorporate it within a PayloadAction<any> type to extend the current type of redux action payload.

function setAttribute<T extends Object, U extends keyof T>(obj: T, key: U, value: T[U]) {
    obj[key] = value;
}

Your assistance is greatly appreciated!

Answer №1

If you're looking to implement a solution similar to this, consider utilizing an intermediary mapped object:

interface CustomState {
  apple: string
  banana: number
  cherry: boolean
}

type CustomPayloads = { 
    [Item in keyof CustomState]: { item: Item, data: CustomState[Item] } 
}[keyof CustomState]
/* this will result in 
type CustomPayloads = {
    item: "apple";
    data: string;
} | {
    item: "banana";
    data: number;
} | {
    item: "cherry";
    data: boolean;
}
*/


// Additionally, you can omit the `: State` declaration here
set(state, action: PayloadAction<CustomPayloads >) {
  const { item, data } = action.payload;
  state[item] = data;
},

Furthermore, I suggest checking out the Redux Style guide for further insights: Model actions as events, not setters.

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

What are some alternatives for integrating React production build files apart from utilizing Express?

Is there a way to integrate React into my library using the HTTP module? I'm trying to figure out how to recursively send static files. Specifically, I want to include the build folder from the React production build, but I'm not sure how to go a ...

I am configuring Jest in my Vite and TypeScript-powered React project

I am having trouble with the relative path of the file I imported in App.test.tsx. It keeps showing me this error message: Cannot find module '@/components/items/card.tsx' from 'src/__tests__/App.test.tsx' Below is the code snippet: // ...

"Unearthing a skeleton within the client component while the server action unfolds in next

One of the challenges I'm encountering involves a client component that initiates a server action. The server action returns a result, which triggers an update in the UI. Take a look at the code snippet provided below for reference export default func ...

Creating an array of Form Groups involves first initializing an empty array and then

Here is a JSON object that I need to create a reactive form based on. What steps should I take for the array portion specifically? { "examName" : "java", "password" : "1234.com", "examCategory" : { "id" : 78 }, "examDetailSet" ...

What is the best way to declare a minimum and maximum date in HTML as the current date?

I have a question regarding setting the min/max date for a date input in my Angular 6 project. How can I ensure that only dates up to the current date are enabled? So far, I have attempted to initialize a new Date object in the ngOnInit function and set t ...

Monitor the closure of a programmatically opened tab by the user

Currently, I am in the process of developing a web application using Angular 11 that interacts with the msgraph API to facilitate file uploads to either onedrive or sharepoint, and subsequently opens the uploaded file in the Office online editor. Although ...

Clicking on the checkbox will trigger the corresponding table column to disappear

Upon clicking the filter icon in the top right corner, a menu will open. Within that menu, there are table header values with checkboxes. When a checkbox for a specific value is selected, the corresponding table column should be hidden. I have already impl ...

The frontend is not triggering the Patch API call

I am having trouble with my http.patch request not being called to the backend. This issue only occurs when I try calling it from the frontend. Oddly enough, when I tested it in Postman, everything worked perfectly. Testing the backend on its own shows t ...

Transforming API data into a particular type using Typescript

I am looking to extract only specific properties from a given object. Can TypeScript interfaces be used to iterate through the data and eliminate unnecessary properties? Sample data: [ 0: { "original_language" : "en", "t ...

The automatic type inference in Typescript is faulty

I am currently working with TypeScript version ^4.1.3 and have developed a REST API that deals with albums and art collections. Before sending the response to the web client, I make sure to remove the userId property from the collections. Below are my Alb ...

Insufficient attributes in TypeScript component for React application

Developing with React import {Input} from '@xxx/forms'; <Input label="account Name" name="account"/> Type Definition for input import React, { Ref } from 'react'; import { InputProps as UITKInputProps } from ...

Middleware in Redux Toolkit is ineffective in managing successful asynchronous actions

After integrating my own middleware into the Redux-Toolkit store using configureStore in my Next.js app, I noticed that the middleware functions appear to be greyed out. I added them via: getDefaultMiddleware({ thunk: { extraArgument: updateNavTabMid ...

Can I assign a value from the tagModel to ngx-chips in an Angular project?

HTML code: <tag-input class="martop20 tag-adder width100 heightauto" [onAdding]="onAdding" (onAdd)="addInternalDomain($event)" type="text" Ts code: addInternalDomain(tagTex ...

typescriptCreating a custom useFetch hook with TypeScript and Axios

I have a query regarding the utilization of the useFetch hook with TypeScript and Axios. I came across an example of the useFetch hook in JavaScript, but I need help adapting it for TypeScript. The JavaScript implementation only handles response and error ...

Using Javascript to parse SOAP responses

Currently, I am working on a Meteor application that requires data consumption from both REST and SOAP APIs. The SOAP service is accessed using the soap package, which functions properly. However, I am facing challenges with the format of the returned data ...

Encountering difficulties in loading environment variables while starting the server using typescript in combination with node.js

My node.js server project, created using typescript, has the following structure: |--node_modules |--server .env |-- build |-- src |-- database |-- controllers |-- models |-- routes |-- utils |-- app. ...

Invoke an ActionCreator within a different ActionCreator

Calling an ActionCreator from another file is proving to be a challenge... The products.ts file contains the ActionCreators and Reducers for Products... import { setStock } from './Store.ts'; //.... export const addProduct = (product: IProduct) ...

What methods are available to me for creating a wrapper for an Angular Component that simply changes the component selector name?

Having experience with React, you can simplify a library component in your app by giving it a new name like this: const MyAppTable = (props) => <LibraryTable ...props />; I'm interested in achieving a similar result in Angular, but I'm ...

Alter the attributes of an instance in a class using a function

Attempting to explain a simple method in TypeScript. This method should allow modification of data for any object type within the data attribute. In simpler terms, we can modify, add, or remove data based on the specified data type, and TypeScript facilit ...

The seamless union of Vuestic with Typescript

Seeking advice on integrating Typescript into a Vuestic project as a newcomer to Vue and Vuestic. How can I achieve this successfully? Successfully set up a new project using Vuestic CLI with the following commands: vuestic testproj npm install & ...