Using the spread operator in Typescript with an object that contains methods

Within my Angular project, I am faced with an object that includes a type and status field where the status can change depending on the type. While some might argue that this is not the best design practice, it is how things are currently structured in my project. The issue I am encountering is that I am unable to utilize the spread operator on this object due to the compiler displaying an error message stating

Property 'getStatusList' is missing in type ...
.

To simplify, the class structure is similar to the following:

export class Foo {
    constructor(
        public type: number,
        public status: number
    ) { }

    getStatusList(): string[] {
        switch (this.type) {
            case 3: {
                return ['Off', 'Interval', 'On Hold']
            }
            default: {
                return ['Off', 'On']
            }
        }
    }
}

This situation arises with TypeScript version 2.9.2 and angular cli version 6.1.1

The code snippet below triggers the aforementioned error. However, while experimenting with sample code in TypeScript Playground, I realized that perhaps using Object.assign could be a solution. Yet, I initially believed that I could easily modify certain properties of an object using the spread operator.

const oldFoo: Foo = new Foo(3, 5);
console.log('old status: ', oldFoo.status);

const newFoo: Foo = { ...oldFoo, type: 1, status: 7 };
console.log('new status: ', newFoo.status);

Answer №1

Utilizing the spread operator in object literals will result in a new object that does not belong to the same class as the original. As stated in the documentation:

The spread operator copies own enumerable properties from a provided object onto a new object.

Through a shorter syntax than Object.assign(), shallow-cloning (excluding prototype) or merging of objects is now possible.

Therefore, you are merely "shallow-cloning" oldFoo. Any methods on the prototype will not be included. For an actual Foo object, it's advisable to construct one properly. Once constructed, you can use Object.assign() for setting multiple properties simultaneously. However, if you're already using a constructor, it's best to initialize with the correct parameters from the start.


It is potential to copy the prototype instead:

const newFoo = { ...oldFoo, type: 1, status: 7 } as Foo;
Object.setPrototypeOf(newFoo, Object.getPrototypeOf(oldFoo));

While this method may work, manipulating prototypes should be approached cautiously.


I hope this information proves helpful. Best of luck!

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

Improving the structure of a TypeScript switch statement

Looking for a more efficient way to implement a switch statement in TypeScript? Here is the current code snippet from a component: switch (actionType) { case Type.Cancel { this.cancel(); break; } case Type.Discard { thi ...

Aligning arguments within the function signature

Is it possible to specify in TypeScript that the method 'foo' always expects FooData, etc. for the following code snippet: const search = (data: FooData|BarData|BazData, method:"foo"|"bar"|"baz") => { //Perform some common operations retu ...

How to resolve the issue of "NGUniversal window is not defined"

I have a newer version of Angular in my application and recently integrated ng-universal. When I attempt to run the command npm run dev:ssr, an error is thrown with the message: ERROR ReferenceError: window is not defined This error originates from a li ...

TypeScript asserts that the Function is not callable

There seems to be an issue with TypeScript not recognizing that a function of type Function is not callable. type Constructable = { new(...args: any[]): any } function isClass(func: any) { return ( typeof func === 'function' && ...

Customizing event typings for OpenTok in Typescript

Currently, I am working on integrating chat functionality using the 'signal' events with the OpenTok API. Here is my event listener that successfully receives the signal: // Listen for signal CHAT_MESSAGE sess.on('signal:CHAT_MESSAGE', ...

What is the best way to establish anchors for *ngFor elements in Angular 2 and beyond?

I have a component that displays items using *ngFor. My goal is to scroll down to the element with anchor #3. Here's the code snippet: @Component({ selector: 'my-app', template: ` <button (click)="scroll(3)">scroll 2</butt ...

Initiate monitoring for child component modifications

I'm looking to disable 'changeDetection' for the parent component while enabling it for the child component. Can you provide an example of how this can be achieved? The parent component contains static data, meaning change detection is not ...

Incorporating Firebase administrator into an Angular 4 project

Currently encountering an issue while trying to integrate firebase-admin into my angular project. Despite my efforts, I am unable to resolve the error that keeps popping up (refer to the screenshot below). https://i.stack.imgur.com/kdCoo.png I attempted ...

Guide on setting up a route in Next.js

Recently, I developed a simple feature that enables users to switch between languages on a webpage by adding the language code directly after the URL - i18n-next. Here's a snippet of how it functions: const [languages, ] = React.useState([{ langua ...

Custom JavaScript files are not recognized by Angular 4 pages unless the page is manually refreshed

I am facing an issue with my custom JavaScript files in Angular. I have imported them all in the angular-cli.json file but the pages do not recognize them unless I refresh the page after navigating from one page to another. Here is a snippet of my angular ...

Unable to access FireReader in Ionic 3, while Ionic 4 functions properly

After building my Ionic project on two different computers, I noticed that I received varying results. On the first computer: Ionic Info Ionic: ionic (Ionic CLI) : 4.2.1 (/usr/local/lib/node_modules/ionic) Ionic Framework : ionic-angular 3.9.2 ...

Ways to fetch information from NGRX store in a linear manner

Struggling to handle NGRX's data access patterns effectively. Currently, I am retrieving data from my NGRX store in the following manner: logBooksAndAuthors() { const books$ = this.store.select(store => store.books); const authors$ = this.s ...

What is the process to activate a function within a component once a service method has been run?

I'm currently working on a chart configuration using amCharts, where an eventListener is registered for the bullets. This event listener then triggers another function in my chart service. My goal is to activate a method in my component as soon as th ...

Angular Material - Data Table Kit

Struggling with setting custom styling for a mat-table in Angular Material. I want to adjust the border radius of the table and change the spacing inside to "space-between". The design I'm aiming for is shown here: Design Any tips or suggestions woul ...

Ensure that missing types are included in a union type following a boolean evaluation

When working with typescript, the following code will be typed correctly: let v: number | null | undefined; if(v === null || v === undefined) return; // v is now recognized as a `number` const v2 = v + 2; However, if we decide to streamline this process ...

Utilizing the "row" and "column" attributes in Angular (Flexbox) results in significant spacing between input fields within the HTML code

I'm working on aligning 2 input fields side by side within the same line. To achieve this, I've been utilizing Flexbox. However, I've observed that when using Flex with both 'row' and 'column', it introduces extra spacing ...

Testing the creation of elements dynamically with jestLooking into jest for dynamically adding

Attempting to test a dynamic element using TypeScript, but struggling to understand the process. Can anyone offer guidance? Below is the TypeScript file: export default class MyClass { constructor(){ this.render(); } render() { ...

tsc and ts-node are disregarding the noImplicitAny setting

In my NodeJS project, I have @types/node, ts-node, and typescript installed as dev dependencies. In the tsconfig.json file, "noImplicitAny": true is set. There are three scripts in the package.json file: "start": "npm run build &am ...

Retrieve a specific JSON object by ID in an Angular Typescript observable

Below is a json string that contains both "stocks" and "contacts" data arrays. Depending on the request, I need to extract either the "stocks" or "contacts" data: [{ "id": "stocks", "name": "Stocks", "data": [ { "id": 1, "name": "Act ...

Prevent the page from closing by implementing a solution within the ionViewWillLeave method

I'm looking to use the ionViewWillLeave method to prevent the page from closing and instead display a pop-up confirmation (using toast.service) without altering the form. ionViewWillLeave(){ this.toast.toastError('Do you want to save your cha ...