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

Retrieving the <html> tag within an Angular component

In an Angular component, the <body> and <head> tags can be accessed by injecting DOCUMENT as shown below: import { DOCUMENT } from '@angular/common'; import { Inject } from '@angular/core'; export class TestComponent { c ...

atom-typescript - What could be causing the unrecognized Typescript configuration options?

I'm puzzled as to why I am encountering the errors depicted in the screenshot below. Atom is indicating that my tsconfig.json file has 'project file contains invalid options' for allowJs, buildOnSave, and compileOnSave. However, according ...

Grab a parameter from the URL and insert it into an element before smoothly scrolling down to that

On a button, I have a URL that looks like this: www.mywebsite.com/infopage?scrollTo=section-header&#tab3 After clicking the button, it takes me to the URL above and opens up the tab labeled tab3, just as expected. However, I would like it to direct m ...

When calling undefined typescript, the async function does not return a value but displays its result afterwards

When I debug my function, it waits until the return statement, but when I call the function, it returns undefined and the errors are also undefined. I'm not sure why this is happening. import userModel from '../Models/user.model'; const bcr ...

Installing and running Node.js within a tomcat server

After creating a web application using Angular, Node/Express, and MySQL, I faced an issue with deployment. My Angular app is running on a tomcat server connected to multiple PCs, but now I need to also deploy my backend (Node.js/Express.js) on the same s ...

Tips for utilizing an elective conversion by typing

In my opinion, utilizing code is the most effective approach to articulate my intentions: interface Input { in: string } interface Output { out: string } function doStuff(input: Input): Output { return { out: input.in }; } function f<Out>(input ...

angular 2 updating material table

Issue at Hand: I am facing a problem with the interaction between a dropdown menu and a table on my website. Imagine the dropdown menu contains a list of cities, and below it is a table displaying information about those cities. I want to ensure that whe ...

Adding query parameters to links in Angular 10: A beginner's guide

I'm trying to update a link: <a class="contact-email" href="mailto:<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="117268737463656364727a51666370617c7065743f727e7c">[email protected]</a>" ...

The recursive component is functional exclusively outside of its own scope

I'm facing an issue where my recursive component is not nesting itself properly. The problem arises when I try to use the Recursive component inside another Recursive component. Although the root is correctly inserted into the Recursive component fro ...

Display the inputs from a reactive form in a different component

I am currently facing a situation where I have multiple components, such as component A, containing a reactive form. The data from these forms is stored in a central service. My goal now is to display a preview of this form in component B. However, upon na ...

How can an Angular4 unit test disregard an HTML tag from a third-party component?

I've exhausted my resources by checking the docs, SO, and attempting various solutions, but I am unable to make this work. The issue arises when writing a unit test for an angular4 application using karma/jasmine. The test is targeting a component tha ...

Having trouble accessing a variable from the material theme in Angular 7

Currently, I am working with Angular 7.0.3 and endeavoring to establish an scss variable with the primary color of my material theme. // src/styles/_variables.scss @import "~@angular/material/theming"; @include mat-core(); $app-primary: mat-palette($mat-i ...

Using Angular 2's ngModel directive to bind a value passed in from an

Using [(ngModel)] in my child component with a string passed from the parent via @Input() is causing some issues. Although the string is successfully passed from the parent to the child, any changes made to it within the child component do not reflect bac ...

Adjusting the Material UI Select handleChange function

const handleObjectChange = (event: React.ChangeEvent<{ value: unknown }>) => { const { options } = event.target as HTMLSelectElement; const selectedValues: object[] = []; for (let i = 0, l = options.length; i < l; i += 1) { if ...

Inheritance in Angular with TypeScript Using Generic Types

Looking for some assistance from the angular2 / typescript experts out there to guide me in the right direction before I lose my mind :-) Here's what I'm trying to achieve: I want to create a parent class that implements its own defined parent ...

Implementing a feature in ReactJS that allows users to upload multiple images in base64 format

I'm trying to develop an image uploader using base64 and I want the output as an array. However, I am encountering an issue where the array is coming out empty!. I suspect it might be due to an asynchronous problem. Any tips on how to incorporate asyn ...

Error: A problem occurred that was not caught in the promise, please investigate further

@Injectable() class MyErrorHandler implements ErrorHandler { handleError(error) { // an error occurred in a service class method. console.log('Error in MyErrorhandler - %s', error); if(error == 'Something went wrong'){ ...

Angular (4, 5, 6, 7) - An easy guide to implementing slide in and out animations using ngIf

How can you implement a basic sliding animation in Angular4 to show and hide a container element? For example: <div *ngIf="show"> <!-- Content --> </div> Slide the content in (similar to jQuery's slideDown() method) from top t ...

Are there any @types available for browser extension objects that are interoperable?

I am in the process of developing a browser extension that would work seamlessly on Edge, Chrome, and Firefox by utilizing Typescript. After coming across an article discussing interoperable browser extensions, I stumbled upon a code snippet: window.brow ...

Creating Instances of Parameterized Types

Consider the following scenario: class Datum {} An error message (error TS2304: Cannot find name 'T') is encountered when attempting the following: class Data<T extends Datum> { datum: T constructor() { this.datum = new ...