NGRX reducer avoids generating errors due to incorrect assignments

My experience with ngrx is relatively new. In my typical TypeScript work, I usually encounter an incorrect assignment error like the one below due to a missing property in the interface declaration:

interface IExample {
  count: number;
}

let initialState: IExample = { count: 0, other: '??????' };

// Type '{ count: number; other: string; }' is not assignable to type 'IExample'.
//   Object literal may only specify known properties, and 'other' does not exist in type 'IExample'.

However, while working on a reducer using the on associator (as I understand it's called), this exception is not thrown and other gets added to the return object without any issues.

interface IExample{
  count: number;
}

let initialState: IExample = { count: 0 };

const reducer = createReducer(
  initialState,
  on(add, (state, { payload }) => ({ 
    ...state,
    other: '??????' 
  })),
);

The signature for the on function is as follows:

on<State, Creators extends readonly ActionCreator[]>(...args: [any, Creators, any, OnReducer<State extends infer S ? S : never, Creators>]): ReducerTypes<State, Creators>

How can I avoid these types of mistakes and ensure that compilation errors are shown as expected?

Note:

"@ngrx/store": "^12.3.0"
,

Answer №1

When examining the reducer on function, it becomes apparent that the return type is not specified. This could result in Typescript being unable to determine the return type automatically. To resolve this issue, it is recommended to specify the return type manually which will then highlight any errors:

interface IExample{
  count: number;
}

let initialState: IExample = { count: 0 };

const reducer = createReducer(
  initialState,
  on(add, (state, { payload }): IExample => ({ 
    ...state,
    other: '??????' //this should now be highlighted as an error
  })),
);

However, it is important to note that this manual specification must be included for each individual on function, which can be quite tedious. It is hoped that this issue will be addressed by NgRx in the future. In my experimentation, I discovered other scenarios where Typescript checks can be bypassed, with one example being the use of Object.assign.

const wrongIExample: IExample = Object.assign(initialState, { another: '????'});
// surprisingly, this does not raise an error

This serves as a reminder that Typescript still has its limitations.

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

Can you please verify the most recent updates for Bootstrap and Syncfusion in my Angular project?

Could someone help me figure out when the bootstrap and syncfusion libraries were last updated in my Angular project? I'm having difficulty finding this information. ...

I'm puzzled as to why my createDoorMethod is returning a string value instead of a number, even though I am passing it a number. Can someone help me

Currently enrolled in a web development course, I am diving into the world of Angular 2 and TypeScript. Despite following along with the video tutorial and using the same code, my implementation is not working as expected, leaving me puzzled. Here is the ...

Accessing data retrieved from an API Subscribe method in Angular from an external source

Below is the Angular code block I have written: demandCurveInfo = []; ngOnInit() { this.zone.runOutsideAngular(() => { Promise.all([ import('@amcharts/amcharts4/core'), import('@amcharts/amcharts4/charts') ...

Typescript includes empty spaces in its duplicate-checking process

I have been working on removing duplicate values from an array using the following code: for (var i = 0; i < a.length; i++) obj[a[i]] = a[i] a = new Array(); // Checking each object with keys to remove duplicates. for (var key ...

Update your code by swapping out two consecutive setTimeout functions with RxJS

When working in an Angular application, there may be a need to execute a method and then trigger two other methods with a time delay between them. The sequence would look like this: Method call -> wait 150 ms -----> second action -> wait 300 ms - ...

Angular: updating a single route triggers multiple 'NavigationEnd' events

I am currently working with Angular 4 and have written the following code in one of my components to detect when a route has changed and reload the page: ngOnInit() { this.router.events.subscribe((value) => { if (value instanceof Navi ...

Testing the value of an input in Angular using unit tests

Currently, I am delving into the official documentation of Angular2 which focuses on unit testing (https://angular.io/docs/ts/latest/guide/testing.html). My struggle lies in setting a component's input field value so that it reflects in the component ...

Discovering the generic type from an optional parameter within a constructor

Looking to implement an optional parameter within a constructor, where the type is automatically determined based on the property's type. However, when no argument is provided, TypeScript defaults to the type "unknown" rather than inferring it as "und ...

Injecting singletons in a circular manner with Inversify

Is it possible to use two singletons and enable them to call each other in the following manner? import 'reflect-metadata'; import { Container, inject, injectable } from 'inversify'; let container = new Container(); @injectable() cla ...

Troubleshooting: Icon missing from React vscode-webview-ui-toolkit button

In the process of developing a VSCode extension using React and the WebUi Toolkit library for components, I encountered an issue with adding a "save" icon to my button. I diligently followed the documentation provided by Microsoft for integrating buttons i ...

Finding a solution to the type issue of error handling in Route Handler with NextJS

I'm working on a route handler located at app/api/transactions/route.ts. Here's a snippet of the code: import { NextRequest, NextResponse } from "next/server"; import { AxiosError } from "axios"; import axios from "../axi ...

What causes the entire set of dynamically created cards to collapse when using the toggle collapse button in ngb-bootstrap's Collapse control?

I am currently implementing the ngb-bootstrap collapse feature in my Angular 9 application. Incorporating the ngb-bootstrap collapse functionality within a Bootstrap card, I have multiple cards being generated. Each card is equipped with a collapse button ...

Implement functionality to update the user interface with raw data received through Bluetooth serial communication

I've been utilizing the plugin https://github.com/don/BluetoothSerial to handle my Bluetooth connection with a HC-06 module on an Arduino Leonardo. Everything is functioning well, except for an issue I am encountering with the mobile application. Here ...

Welcome to the awe-inspiring universe of Typescript, where the harmonious combination of

I have a question that may seem basic, but I need some guidance. So I have this element in my HTML template: <a href=# data-bind="click: $parent.test">«</a> And in my Typescript file, I have the following code: public test() { alert( ...

Creating a Universal Resolver in Angular (2+) - A Step-by-Step Guide

I have a vision to develop an ultra-generic API Resolver for my application. The goal is to have all "GET" requests, with potential extension to other verbs in the future, utilize this resolver. I aim to pass the URL and request verb to the resolver, allow ...

What is the correct method for service injection in Angular 8?

I have encountered an issue while trying to inject a service into my main "App" component. The error message is shown in the screenshot below: constructor(private newsApi: NewsApiService) {} Upon importing the service using the code above, I received the ...

What is the method for defining a constant data type with a class property data type in typescript?

I've been working on developing a nestjs API and have been using classes to define my entities. For instance, I have created a Customer entity as shown below: export class Customer { id: number; name: string; } Now, while working on my Custom ...

Trouble arises when trying to test an Angular service that relies on abstract class dependencies

Currently, I am working on a service that has a dependency on another service, which in turn relies on two abstract classes as dependencies. (ThemeConfigService -> (SettingsService -> SettingsLoader, NavigationLoader)) During testing, the failure oc ...

The Angular/Express application is in search of outdated JavaScript files within the Chrome browser

When updating and deploying my Angular web app on Google App Engine with an Express server, I encounter a peculiar issue. Upon refreshing the browser, I sometimes face a blank page accompanied by the following error: main.f2b54282bab6f51a.js:1 Failed to lo ...

Steps to implement the click functionality on the alert controller and modify the language in Ionic 4

I am currently developing a multilingual Ionic 4 app and have implemented the alert controller to display language options. However, I am facing an issue on how to dynamically change the language based on user selection. Below is my app.component.ts code ...