How should a function be correctly implemented to accept an object and modify its attributes?

I have a question regarding the update method in my code. In the function below, it takes an object called newState and uses Object.assign() to update the properties of the class instance. I want TypeScript to only allow:

  • An object as input
  • Properties that are keys of the State Class
  • Values for those properties that match the respective types

Did I correctly define this method? Is there a better or alternative approach to achieve this?

Furthermore, in main.ts, when implementing StateInterface on the State class, the TypeScript compiler shows an error stating that the parameter newState in the update method is implicitly any. Shouldn't it be getting type information from types.d.ts?:

/// types.d.ts
export interface StateInterface {
    user: User;
    fileList: DirectoryResponse;
    selectedFiles: Array<SelectedFile>;
    currentDir: string;
    response: APIResponse;
    menu: Menu;
    dialog: Dialog;
    history: object;
    update: <P extends StateInterface, T extends keyof StateInterface>(newState: { [key in T]: P[T]}) => Promise<void>;
    syncPage: () => void;
}

/// main.ts
class State implements StateInterface {
    user: User;
    fileList: DirectoryResponse;
    selectedFiles: SelectedFiles;
    currentDir: string;
    response: APIResponse;
    menu: Menu;
    dialog: Dialog;
    history: History;

    constructor(user: User, fileList: DirectoryResponse, selected: SelectedFiles, currentDir: string, response: APIResponse, menu: Menu, dialog: Dialog, history: History = { forward: false, back: false }) {
        this.user = user;
        this.fileList = fileList;
        this.selectedFiles = selected.slice();
        this.currentDir = currentDir;
        this.response = response || { fileResults: [], folderResults: [] };
        this.menu = menu || { location: '', type: 'folder' };
        this.dialog = dialog || { type: "", state: false };
        this.history = history;
     }

     get dir() {
         return this.currentDir.slice(1).split('/');
     };

     async update(newState): Promise<void> {
                  ^^^^^^^^ (implicit any)
         if (newState) {
             Object.assign(this, newState);
         } 
         
         this.fileList = await readDir(this.currentDir).then(r=>r.json());
     }
}

Answer №1

When you write StateInterface, it suggests that you only intend to include keys from StateInterface in the newState variable, excluding any other properties that may already exist in the State.

If this is what you are aiming for, I suggest typing the update method in both the interface and class like so:

update(newState: Partial<StateInterface>): void {
  ...
}

It's important to keep in mind that using Partial allows functions from StateInterface to be overwritten, so you might consider using Omit to remove any unwanted keys instead.

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

Ways to stop bootstrap tabs from ruining inactive content? [keeping track of tab status]

Although Bootstrap tabs are useful, a common issue is that content on inactive tabs is removed from the page flow. When switching to a new tab, the previous tab's display attribute is set to none instead of using visibility: hidden or other methods. ...

Iframe overlay feature functioning on Chrome but not on IE11

I have a Document viewer with a .less file containing the following styling: div.document-previewer-container { //height: 400px; //width: 300px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; //padding: 5px 2px; > div.document-preview { h ...

Retrieving input values with JQuery

HTML <td data-title="Quantity"> <div class="clearfix quantity r_corners d_inline_middle f_size_medium color_dark m_bottom_10"> <button class="btn-minus bg_tr d_block f_left" data-item-price="8000.0" data-direction= ...

Ways to center vertically aligned buttons within cards in a React application with Material-UI

I've encountered an issue with my ReactJS project using material-ui. I created 3 cards, each with a paragraph of varying lengths. This caused the buttons to be misaligned vertically in each card, as the position differs due to paragraph size differenc ...

What could be causing the issue with file_get_contents not loading the phpscript correctly in this scenario?

In my coding experience, I created a piece of code that essentially accomplishes the following: <div id="thisDiv"> </div> <?php echo "<script>document.getElementById('thisDiv').innerHTML = '".addslashes(str_replace(arr ...

Is the validity of the expression !args.value || args.value.length true?

After analyzing this segment of code, I noticed an interesting expression: !args.value || args.value.length For instance, consider the following scenario: let v = {}; console.log(!v.value); //outputs true console.log(v.value); //outputs undefined con ...

update the data source of the material table inside the subscription

Seeking guidance for updating a MatTable datasource within an Angular application. The current Typescript code involves fetching data from an API using AdminService, iterating over the results to make additional API calls for more information about a fleet ...

Can you explain how to incorporate global functions from a javascript library into an Angular 2 project?

Recently I started working with angular-cli and came across a situation where I have an index.html containing a javascript script with some global functions. I want to access these functions in multiple parts of my application. As someone who is new to A ...

Server unable to start and error message shown on command prompt

I am having trouble opening the webpage from the code hosted on Github. When I try to run the server, I encounter errors that are displayed in the command prompt as shown below: Code link: https://github.com/mschwarzmueller/nodejs-basics-tutorial/tree/mas ...

Issue with updating Parent value in Vue component when Child value changes

I am working with an Array to fill a Dialog Vue Component. My setup looks like this: basicInfo: [{ firstName: "John" , lastName: "Doe" }], <basicInfoForm v-model="showBasicInfoForm" :basicInfo="newbasicInfo[0]"></basicInfoFo ...

Trouble with FilterBy Feature in Bootstrap-Table

I am attempting to use filtering functionality with a table that is populated via JSON, utilizing bootstrap-table by wenzhixin. HTML snippet: <button class="btn btn-primary" id="filterBtn">Filter</button> <div class="container"> &l ...

Issue encountered: Failure to locate module 'socket.io' while attempting to execute a basic server JavaScript file

Below is my server.js file that I am attempting to run using node server.js: var app = require('express')(); var http = require('http').createServer(app); var io = require('socket-io')(http); //also tried socket.io instead of ...

Guide to organizing documents using an interface structure

I currently have an interface that outlines the structure of my documents within a specific collection: interface IGameDoc { playerTurn: string; gameState: { rowOne: [string, string, string] rowTwo: [string, string, string] ...

A method for utilizing wildcards in conjunction with the .load function

Currently, I am utilizing jquery, jquery mobile, js, html, and css within Phonegap to develop my android/ios application. However, my understanding of js & jquery is somewhat limited. In my index.html file, I use .load to load other html files into s ...

Guide on transferring session-specific information from the server to the client via express APIs

In order to display the username in the chat section of our web application, we are utilizing websockets for real-time communication. However, we are facing an issue where the chat page is rendered as an API response using res.render(). Inside this HTML re ...

Angular 2 issue with nested form elements

Looking to build a form that includes nested sub/child components within it. Referring to this tutorial: https://scotch.io/tutorials/how-to-build-nested-model-driven-forms-in-angular-2 https://plnkr.co/edit/clTbNP7MHBbBbrUp20vr?p=info List of modificatio ...

Issue with Multer s3 upload: File not functioning properly in s3 and size increase of file

I successfully uploaded an mp4 file to s3 using node.js and the code seems to be functioning well as I can see the file in s3. However, there seems to be a discrepancy in the file size. The original file is 860kb but after uploading it, it increases to 1.4 ...

Transferring 'properties' to child components and selectively displaying them based on conditions

This is the code for my loginButton, which acts as a wrapper for the Button component in another file. 'use client'; import { useRouter } from 'next/navigation'; import { useTransition } from 'react'; interface LoginButtonPr ...

Leveraging icons with Bootstrap 4.5

I am currently exploring how to incorporate Bootstrap 4.5 icons using CSS. Do you have any examples of code that could guide me on how to achieve this? I am specifically interested in understanding the required CSS declarations that would allow me to use t ...

"Printed within the custom directive, the ng model value shows up as undefined

I am currently in the process of creating a custom directive that involves a simple template consisting of an input type textarea. I am assigning the ng-model to ngmodel and creating a link function where I am trying to capture the value of ngmodel. Howeve ...