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

Retrieve State from Store in Routing Configuration File [using react-router v4 and redux-thunk]

I'm currently in the process of creating a ReactJS web application (still learning the ropes). In my project, I am making use of react-router v4 and redux-thunk. I'm seeking guidance on how to retrieve the current state value from my store withi ...

Utilizing nested redux-forms to include a voucher form within a checkout form

I am currently working on developing a checkout page that includes a nested coupon code or voucher subform using redux-form. The checkout form will have options like Country selection, and within this form, I want to add a sub form for applying a Voucher. ...

I am facing difficulty in transmitting data from the map function within my React modal component

Although I understand the code is not great, I'm struggling with this part. My goal is to send the id data collected in the map function to the redux thunk called updatePersonal. Big thanks to all my friends who helped me out with this issue. const ...

Tips for arranging various information into a unified column within an Antd Table

Is there a way to display multiple data elements in a single cell of an Ant Design table, as it currently only allows insertion of one data element? I am attempting to combine both the 'transactionType' and 'sourceNo' into a single cell ...

next-intl failing to identify the primary language setting

When testing next-intl for the app directory in the Next.js v13.4.0, I encountered an issue where the default locale was not recognized. Despite following the documentation step by step, I also faced significant challenges with the client-side version in p ...

Tips for triggering an error using promise.all in the absence of any returned data?

I'm dealing with an issue in my project where I need to handle errors if the API response returns no data. How can I accomplish this using Promise.all? export const fruitsColor = async () : Promise => { const response = await fetch(`....`); if( ...

Error message: Material Design UI - The type 'string' cannot be assigned to the type Icon

I am currently working on a component that is responsible for returning the specific icon based on the prop that is passed. Here is a simplified version of how it works in my application: import * as icons from "@mui/icons-material"; interface I ...

React Type Mutation response feedback is a valuable tool for receiving input

I am facing an issue with passing the mutation success response in my code. I have a file named change-email.tsx which calls a component file updateEmail.tsx containing a mutation function. The submit function is working fine, but I cannot figure out how t ...

Definition of union types in JavaScript using Typescript

Looking for assistance in creating a d.ts file for the union-type library found at https://github.com/paldepind/union-type Consider the following union type: let Maybe = Type({ Nothing: [] , Just: [Number] }) I am interested in setting up compi ...

The process of implementing ngOninit with asynchronous data involves handling data that may take

Within the ngOnInit method, I am calling a service method and assigning the return value to a member variable. However, when trying to access this variable later in the ngOnInit again, it seems that due to synchronization issues, the value has not been ass ...

Steps for making a "confirm" button within a modal that includes a redirect URL

I have developed a modal that, upon clicking on the confirm button, should redirect the user to the page titled securities-in-portfolio. modal <div class="modal-footer justify-content-center"> <button type="button" class ...

How can I showcase a different component within another *ngFor loop?

I am currently working on a table in HTML that displays product information. Here is the code snippet for it: <form [formGroup]="myform" (ngSubmit)="submit()" > <tbody> <tr class="group" *ngFor="let item of products;"&g ...

Tips for resolving the error of encountering a forbidden and unexpected token in JSON at position 0 while using React hooks

const [forecastData, setForecastData] = useState({ forecast: []}); useEffect(() => { let ignore = false; const FETCHDATA = async () => { await fetch(forecast,{ headers : { ...

What is the reason behind TypeScript failing to provide type safety in a generic higher order component which introduces extra properties into React components?

I'm currently working on developing a versatile higher order component, but have encountered an issue with type safety not being enforced. Interestingly, when attempting the same implementation without using generics, the type safety is verified as ex ...

Utilizing React Custom Hooks for Firestore Data Retrieval

I recently developed a React custom hook that interfaces with a Firestore database. I followed the guidelines provided on the Firebase website, but I encountered an issue upon re-rendering the component. After refreshing my app, the useEffect hook function ...

Create a specific definition for a packaged item with limited access

As I worked with a package that lacked types, I took the initiative to create a type definition for it. The specific package in question is react-date-range. In order to accommodate this new type definition, I established a directory where it could be loca ...

In the en-US locale, the toLocaleDateString function is transforming "00:30" into 24:30

Questioning the Conversion of Time from 00:30 to 24:30 in en-US Locale options = { year: "numeric", day: "numeric", month: "numeric", hour: '2-digit', minute: '2-digit&apo ...

TypeScript Add Extract Kind

I am currently working on implementing a function called sumPluck. This function will allow the user to specify a property of type number from an object in an array, and then calculate the sum of all those properties. For example: type A = { prop: number ...

Assigning string properties to different types

I have numerous data types, each with a common property called dataType, and I am currently mapping each one to that specific value: interface GroupData { dataType: "group"; name: string; people: PersonData[]; } interface PersonData ...

Angular 2 Issue: Error Message "Cannot bind to 'ngModel'" arises after FormsModule is added to app.module

I've been struggling with the data binding aspect of this tutorial for over a day now. Here's the link to the tutorial: https://angular.io/docs/ts/latest/tutorial/toh-pt1.html The error I keep encountering is: Unhandled Promise rejection: Tem ...