Spread operator in TypeScript does not interact properly with a specific type

Currently, I am working with a redux-style reducer in ngrx that returns a specific type. However, I have encountered an issue where the TypeScript linter fails to catch invalid properties when using the spread operator in my return object.

Below is the interface I am working with:

interface MyState {
    firstName: string;
    lastName: string;
    age: number;
}

Here is my reducer. The Action parameter represents an ngrx action:

function reducer(state = initialState, action: Action): MyState {
    switch (action.type) {
        case Actions.COOL_ACTION:
            return {
                ...state,
                propertyDoesNotExist: action.payload, // <- no error
            };
        default:
            return state;
    }
}

Although I would expect propertyDoesNotExist to be flagged as an error, it is not. I have attempted casting the return object as <CalendarState>, using ...(<CalendarState>state) for the state property, and trying the as alias, but none of these solutions have worked.

It seems like the use of the spread operator might be causing issues with the types.

Answer №1

When using ...state, the resulting expression changes from an object literal, avoiding TypeScript complaints if it's a subtype of the return type and contains additional properties. I faced this challenge myself and created a simple helper function to handle extra properties:

const applyChanges = <S, K extends keyof S>(state : S, changes : Pick<S, K>) : S =>
  Object.assign({}, state, changes);

(I chose to use Object.assign instead of spread operators due to issues like this: https://github.com/Microsoft/TypeScript/issues/14409)

To implement applyChanges, simply replace

return {...state,
    propertyDoesNotExist: action.payload, // <- no error
};

with

return applyChanges(state, {
    propertyDoesNotExist: action.payload, // <- error
});

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

A guide to retrieving error response data using axios AsyncThunk typing

I'm struggling to access the error response data. The code worked fine in JavaScript, but since moving to TypeScript, things have gotten confusing. Currently, I'm seeing 'error' is of type 'unknown'.ts(18046) export const regi ...

Awaiting a response before triggering

Currently, I'm utilizing Serverless to build a REST get endpoint. The main goal is to request this endpoint and receive a value from the DynamoDB query (specifically from the body tag). The issue I am facing is that when this endpoint is invoked, the ...

Exporting Axios.create in Typescript can be accomplished by following a few simple

My code was initially working fine: export default axios.create({ baseURL: 'sample', headers: { 'Content-Type': 'application/json', }, transformRequest: [ (data) => { return JSON.stringify(data); } ...

Problem with Invoking method of parent component from child component in Angular 4

Despite having all my event emitters set up correctly, there's one that seems to be causing issues. child.ts: @Component({ ... outputs: ['fileUploaded'] }) export class childComponent implements OnInit { ... fileUploaded ...

Utilizing shared components across a Next.js application within a monorepo

Utilizing a monorepo to share types, DTOs, and other isomorphic app components from backend services (Nest.js) within the same mono repo has presented some challenges for me. In my setup, both the next.js app and nest.js app (which itself is a nest.js mono ...

Possible Problems that Could Occur if I Give a Custom MUI Component the Same Name as the Default Component?

As I dive into a ReactJS project utilizing MUI, I find myself tasked with theming components to align with our company's UX design guidelines. Many components can be easily customized using the MUI theme provider. However, certain components require ...

Mongodb Dynamic Variable Matching

I am facing an issue with passing a dynamic BSON variable to match in MongoDB. Here is my attempted solutions: var query = "\"info.name\": \"ABC\""; and var query = { info: { name: "ABC" } } However, neither of thes ...

"Error encountered: Unable to resolve dependency tree" message appears when attempting to run npm install

Encountering dependency errors while trying to execute the npm install command for my Angular application. As a newcomer to TypeScript and Angular, I'm unsure of the next steps to take. Any suggestions? Attempted solutions include clearing the npm ca ...

Having trouble with installing Typescript on a MacBook?

I have been attempting to follow the instructions provided on TypeScriptLang.org but for some reason, I am unable to successfully download typescript. This is what I have tried so far: mkotsollariss-MacBook-Pro:/ mkotsollaris$ which node /usr/local/bin/n ...

Exploring the versatility of Vue.js through props and scoped slots

Coming from a React background, I am used to being able to easily alter children components before they render. However, after spending hours reading the VueJS documentation and searching forums, I have not been able to find a straightforward way to do thi ...

Passing a parameter from a redirect function to an onClick in React using TypeScript

I am facing a challenge in passing a parameter to my redirectSingleLocker function. This function is intended to take me to the detailed page of a specific locker, identified by a guid. The lockerData.map method is used to display all the JSON data in a ta ...

Revealing the Webhook URL to Users

After creating a connector app for Microsoft Teams using the yo teams command with Yeoman Generator, I encountered an issue. Upon examining the code in src\client\msteamsConnector\MsteamsConnectorConfig.tsx, I noticed that the webhook URL w ...

Encountering an Issue with Dynamic Imports in Cypress Tests Using Typescript: Error Loading Chunk 1

I've been experimenting with dynamic imports in my Cypress tests, for example using inputModule = await import('../../__tests__/testCases/baseInput'); However, I encountered an issue with the following error message: ChunkLoadError: Loading ...

The paths configuration in tsconfig.json is not functioning as anticipated

I've been encountering a module not found error while trying to work with jasmine-ts. To troubleshoot, I decided to use tsc and inspect my folder structure: \src\app\... \src\tests\... To address this issue, I created a ...

The parameter type 'typeof LogoAvatar' cannot be assigned to the argument type 'ComponentType<LogoProps & Partial<WithTheme>'

Why is the argument of type typeof LogoAvatar not assignable to a parameter of type ComponentType<LogoProps & Partial<WithTheme>? Here is the code snippet: import * as React from "react"; import { withStyles } from "@material-ui/core/style ...

Using Angular2 to bind HTML markup to a boolean flag and trigger a method when the flag is set

I'm currently developing a solution for Angular 2 Bootstrap Datepicker to automatically close when a user clicks outside of it. My current approach involves tracking external clicks and updating a boolean flag as shown below: @Component({ select ...

Narrowing Types Based on a Conditional List of Keys

Below is the code snippet I am currently working with: type AlphaNumeric = string | number | null | boolean | undefined; type AlphaNumericKeys<T> = { [key in keyof T]: key extends string ? (T[key] extends AlphaNumeric ? key : never) : never; }[k ...

How to access properties of objects within an array in Angular 4

Is there a method to call only the $values from each rate record in my array that I want to read? https://i.sstatic.net/MT2XK.png This is what I have done to access this array: async ngOnInit() { this.product$ = await this.reviewService.getReview(th ...

How to invoke a function from a different controller in Ionic 2

Is it possible to call a function in another controller within Ionic 2? Here is my code where I want to call the loadPeople function in the tab controller. home.ts import { Component } from '@angular/core'; import { NavController } from ' ...

Kendo checkbox toggle issue with switching between true and false states is not functioning correctly

How can I make a button appear when one or more checkboxes are clicked? Currently, the toggle function only activates when I select one checkbox, and then deactivates upon selecting another. Any guidance on improving this functionality would be greatly app ...