Unable to assign a value to a constant within the class constructor

I'm aware that in TypeScript, readonly properties can only be assigned a value within a class constructor. However, I encountered an error while trying to do so inside the constructor of my class, specifically related to an array method handler.

class MyClass {
    readonly alpha: number

    constructor(settings: Options) {
        ;(Object.keys(settings) as Array<keyof Options>).forEach((key: keyof Options) => {
            // This is not allowed (error: Cannot assign to '...' because it is a read-only property.)
            this[key] = settings[key]

            // Also not allowed
            this.alpha = settings.alpha
        })

        // This is allowed
        this.alpha = settings.alpha

        // This is also allowed
        const key = 'alpha'
        this[key] = settings.alpha
    }
}

Playground Link

Can anyone explain why this error occurs and suggest a way to handle it without compromising the use of an array method?

Answer №1

interface Config {
    option1: string
    option2: number
    option3: boolean
}

function retrieveKeys<T extends Record<string | number, unknown>>(
    data: T
): ((keyof T & string) | (`${keyof T & number}`))[] {
    return Object.keys(data);
}

class NewClass {
    readonly option1!: string
    readonly option2!: number
    readonly option3!: boolean

    constructor(configuration: Config) {
        for (const key of retrieveKeys(configuration)) {
            this[key] = configuration[key];
        }
        for (const key of Object.keys(configuration) as (keyof Config)[]) {
            this[key] = configuration[key];
        }
        // in situations like this, sometimes I simply use 
        Object.assign(this, configuration)
        // whether it's `option1!: string` or `option1 = 'default'`
    }
}

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

Denied rendering of design due to incompatible MIME type

Just delved into the world of node / express and decided to test my skills by creating a simple tip calculator app. However, I seem to have hit a roadblock with loading my CSS. The console keeps throwing this error: "Refused to apply style from &apos ...

Select the input based on the name and value provided from a radio button using jQuery

I want to show a div element when the user chooses option 4 from a radio button. $(document).ready(function () { $("#GenderInAnotherWay").hide(); $("input[name='Gender'][value=4]").prop("checked", true); $("#GenderInAnotherWay").tog ...

Unable to display image source in viewport

Currently, I am working on developing a basic ionic app that interacts with an API that I have created. I am encountering an issue where all data is being displayed correctly in the view except for the src attribute of an image. When I use console.log to c ...

Developing an Angular 2 Cordova plugin

Currently, I am in the process of developing a Cordova plugin for Ionic 2. The plugin is supposed to retrieve data from an Android device and display it either on the console or as an alert. However, I am facing difficulty in displaying this data on the HT ...

What are the best scenarios for implementing anonymous JavaScript functions?

I am currently exploring the reasons behind using anonymous JavaScript functions. Can you list out the distinctions between these functions? Describe scenarios where each function would be appropriate to use. var test1 = function(){ $("<div />" ...

React.js issue with onChange event on <input> element freezing

I am experiencing an issue where the input box only allows me to type one letter at a time before getting stuck in its original position. This behavior is confusing to me as the code works fine in another project of mine. const [name, setName] = useStat ...

Executing multiple server-side methods on an AJAX call in ASP.NET MVC: A comprehensive guide

I am facing a situation where I have a method that is called by jQuery, and its result is displayed on a popup. Sometimes, it takes some time to complete and a blank popup appears with processing message. When clicking on close, the popup disappears but th ...

What's the best way to implement image size and type validation, specifically for .jpg and .png files, using Multer?

When using multer to receive files from the FrontEnd, I need to validate the image size to ensure it's less than 1MB. Additionally, I want to restrict the accepted file types to .jpg, .jpeg, and .png only. const multer = require("multer"); c ...

Is it recommended to place the styles created by material-ui for child components after the styles generated for the parent component?

Utilizing material-ui, which utilizes JSS for styling a website. I have a component named Layout that applies margin to all its children (using the all children selector & > * in its style). This functionality works, but I would also like the child ...

Updating dependencies of dependencies in npm: A step-by-step guide

I'm puzzled by the fact that I can't seem to find a solution to this seemingly easy question. It's surprising that even running npm update doesn't resolve the issue. While I can't post my entire dependency tree here, I'll do ...

What specific element is being targeted when a directive injects a ViewContainerRef?

What specific element is associated with a ViewContainerRef when injected into a directive? Take this scenario, where we have the following template: template `<div><span vcdirective></span></div>` Now, if the constructor for the ...

The autocomplete functionality with ajax is currently malfunctioning

<script> function autocomplet1() { var min_length = 0; // minimum characters to display the autocomplete var keyword = $('#select01').val(); if (keyword.length >= min_length) { $.ajax({ url: 'barcode ...

Having trouble accessing the scrollHeight property of null when using Selenium WebDriver

I am currently working on a function in my code that is responsible for scrolling the page. This particular function was inspired by code used to scrape Google Jobs, which can be found here. However, I encountered an error that reads "javascript error: Ca ...

Disabling the scrollTop() effect following a click event with onClick()

Utilizing the scrollTop() event to toggle the visibility of a div at a specific position and also using the onClick() event to permanently hide the div. While the events are functioning properly, an issue arises when scrolling the page causing the div to r ...

"Let's delve into the world of dynamic variables and Javascript once

As a newcomer to JS, I've scoured countless posts for solutions, but nothing seems to work for me. The issue arises when trying to abstract the code to handle all variables rather than just explicitly expressed values. I am open to alternative method ...

The $geoNear operator must be the initial stage in a pipeline to be valid

When performing an aggregation using nodejs as the server-side language, I encountered the error message $geoNear is only valid as the first stage in a pipeline. This is the Aggregation Object: [ { '$geoNear': { near: [Object], distanceFie ...

Tips for handling a disabled button feature in Python Selenium automation

When trying to click this button: <button id="btn-login-5" type="button" class="m-1 btn btn-warning" disabled="">Update</button> I need to remove the disable attribute to make the button clickable. This ...

Unable to dynamically load a component into page.tsx within Next.js

When importing a component into another component there are no issues, but when trying to import a component into a page it results in an error... I am new to this so any help is greatly appreciated. This is how I am importing: const CodeSampleModal = dy ...

Efficient way to handle nested variables in templates with Nunjucks or alternative approaches

Recently I've been exploring the world of gulp and nunjucks templating, specifically for creating emails. One challenge I'm facing is figuring out how to call a module/partial and assign different values to its attributes each time it's pro ...

What is the best way to dynamically determine the base path for my templates in Angular 2?

Is it possible to dynamically define the base path of two versions of each template in order to use one or the other through configuration? How can I declare TEMPLATES_PATH so that it can be implemented as shown below: component.ts @Component({ temp ...