Ensuring the TypeScript reducer is properly validated with the corresponding action types

I am currently grappling with creating a TypeScript redux reducer that can effectively handle different action types. However, I am facing difficulties in defining the appropriate interface for my state, leading to the error message below:

TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'SampleState'. No index signature with a parameter of type 'string' was found on type 'SampleState'.

https://i.sstatic.net/Y2VvL.png

Can someone guide me on how to correctly implement type checking for my reducer when handling various action types? Below is a snippet of the code for reference.

sampleActionTypes.ts:

export const FOO = 'FOO';
export const BAR = 'BAR';
export const TURN_ON = 'TURN_ON';
export const TURN_OFF = 'TURN_OFF';

interface TurnOn {
  type: typeof TURN_ON;
  actionType: string;
}

interface TurnOff {
  type: typeof TURN_OFF;
  actionType: string;
}

export type Types = TurnOn | TurnOff;

sampleReducer.ts:

import { BAR, FOO, TURN_OFF, TURN_ON, Types } from './sampleActionTypes';

export interface SampleState {
  [FOO]: {
    toggle: boolean;
  };
  [BAR]: {
    toggle: boolean;
  };
}

const initialState: SampleState = {
  [FOO]: {
    toggle: false,
  },
  [BAR]: {
    toggle: false,
  },
};

const sampleReducer = (state = initialState, action: Types): SampleState => {
  switch (action.type) {
    case TURN_ON:
      return {
        ...state,
        [action.actionType]: {
          ...state[action.actionType],
          toggle: true,
        },
      };
    case TURN_OFF:
      return {
        ...state,
        [action.actionType]: {
          ...state[action.actionType],
          toggle: false,
        },
      };
    default:
      return state;
  }
};

export default sampleReducer;

Answer №1

Your state is structured with keys like FOO | BAR according to your defined SampleState interface. Additionally, the data type for your Types['actionType'] is specified as string.

Therefore, when you reference state[action.actionType], it essentially translates to SampleState[string]. However, keep in mind that SampleState only accepts values of FOO or BAR!

To address this issue and align with your requirements, consider typing

Types['actionType']: (typeof FOO) | (typeof BAR)
(or something similar).

Furthermore, pay attention to how you label your fields. While it may be used for illustration purposes, having both actionType and type within an action interface can be redundant and potentially confusing.

Answer №2

To resolve the problem, I made a modification to the SampleState interface by updating it as shown below:

export interface SampleState {
  [key: string]: {
    active: boolean;
  };
}

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

The data type 'number | undefined' cannot be assigned to type 'string' in TypeScript

Need help fixing the number error and converting it to a string? Check out this code snippet: <FlipNumbers height={12} width={12} color="white" background="red" ...

Struggling to bring in components in ReactJS

My journey with ReactJS has just begun, and I've encountered some issues with the code that I believe should work but doesn't. To start off, I set up a new ReactJS project using the npm command create-react-app. Following this, I installed Googl ...

What is the best way to efficiently filter and process two arrays of objects?

I am struggling to efficiently match and update objects from 2 arrays with different key combinations. Despite trying various .filter combinations, I have not been successful yet. My goal is to update the masterList based on the selectionList. for (let se ...

What's the simplest method for updating a single value within a nested JSON object using TypeScript?

Using TypeScript version ^3.5.3 Consider the following JSON data: const config = { id: 1, title: "A good day", body: "Very detailed stories" publishedAt: "2021-01-20 12:21:12" } To update the title using spread synta ...

The functionality of TypeScript's .entries() method is not available for the type 'DOMTokenList'

I'm currently working with a stack that includes Vue3, Vite, and TypeScript. I've encountered an issue related to DOMTokenList where I'm trying to utilize the .entries() method but TypeScript throws an error saying Property 'entries&apo ...

Web application is not making API calls

Currently, I am experimenting with calling data from an API to create a simple weather application for practice purposes. I have been using the inspect element feature in my Chrome browser to check if the console will show the data log, but unfortunately, ...

Implement zoom functionality on a line chart using d3js

I am currently working on integrating a d3js V4 chart into an Angular 4 application. The chart is designed to show multiple sets of data as individual lines. One issue I am facing is getting the zoom feature to function correctly, specifically on the X-ax ...

Executing a TypeScript function directly in HTML without the need for a click event

I understand how to trigger a TypeScript function when clicking a button, but how can I initiate a function without relying on a specific event? My goal is to call a function once an array named chartData has been populated. Here is the code snippet I have ...

Using Typescript to specify the type of data returned from a POST request

In my code, I am making a post request using got in the following way: const got = got_.extend({ prefixUrl: serviceUrl, responseType: 'json' }) const { body } = await got.post('newAddress', { json: { userId } }) The conten ...

Modifying an element's value according to user input: Step-by-step guide

Within my dropdown menu, there is a single option labeled "Others". Upon selecting this option, a textbox appears allowing me to input custom text. Is it possible to dynamically update the value of the <option value="Others">Others</option>, ...

tips for deactivating routerLink functionality on anchor elements

Working on an Angular application that requires me to create an image slider. However, due to the presence of router links in the application, the anchor tags in the image slider keep redirecting. I want to prevent this redirection and instead successful ...

Able to successfully access user account on Postman, however encountering login issues when trying to do

If I can successfully log in a user using Postman, does that indicate there is a bug in my front end code? Encountered CastError: Casting to string failed with value "{ email: '[email protected]', password: '123456' }" (type Objec ...

What steps should be followed in order to generate a child or item with no assigned key

Here is my TypeScript code designed to automatically record the time of data creation: import * as functions from 'firebase-functions'; export const onAccCreate = functions.database .ref('/Agent/{AgentID}') .onCreate((snapshot, contex ...

Tips for adjusting HighCharts layout with highcharts-vue integrations

I have a fairly simple component: <template> <div> <chart v-if="!loading" ref="priceGraph" constructor-type="stockChart" :options="chartData" ...

Ways to avoid using a specific type in TypeScript

Imagine having a class that wraps around a value like this: class Data<T> { constructor(public val: T){} set(newVal: T) { this.val = newVal; } } const a = new Data('hello'); a.set('world'); // typeof a --> Primitiv ...

Can you explain the distinction between declaring a map in TypeScript using these two methods?

When working in TypeScript, there are two different ways to declare a map. The first way is like this: {[key:number]string} This shows an example of creating a map with keys as numbers and values as strings. However, you can also define a map like this: M ...

Enhance your Javascript code performance by efficiently identifying IDs within a list and linking them to a tree structure

Looking for a way to improve the performance of the logic used for iterating over tree data and applying 'dataState' to 'FAILED' if there are matching error ids. interface IData { id: string; label: string; . value: string; expa ...

Executing npm prepublish on a complete project

I am facing a situation with some unconventional "local" npm modules that are written in TypeScript and have interdependencies like this: A -> B, C B -> C C -> D When I run npm install, it is crucial for all TypeScript compilation to happen in t ...

Encountering Issues with NextJS Dynamic SSR: Mobile Devices stuck on loading screen

Issue: The dynamic import feature of Next JS is encountering loading issues specifically on mobile browsers such as Google Chrome and Safari on IOS. Strangely, the functionality works smoothly on desktop browsers like Google Chrome and Mozilla. The projec ...

Is there a preferred method for correctly nesting components?

It may seem like a simple question, but I couldn't find the answer in the documentation or code examples. Consider this example: import { FlowIdentification } from "./flow-identification"; @customElement("bb-flow") export class R ...