What steps can be taken to resolve the TS2322 error that occurs while attempting to assign data[prop] to this

I am facing a problem with the code snippet below and need help resolving it. Can anyone provide guidance on how to fix this issue?

type Data = {
  id: number,
  name: string
}

class Person {
  id: number
  name: string

  constructor(personData: Data) {
    this.id = personData.id
    this.name = personData.name
  }

  update(updateData: Data) {
    for (const prop in updateData) {
      this[prop as keyof Data] = updateData[prop as keyof Data]
    }
  }
}

Playground link

The Issue:

TS2322: Type 'string | number' is not assignable to type 'never'.   Type 'string' is not assignable to type 'never'.

The crux of the problem lies in the update method:

this[prop as keyof Data] = updateData[prop as keyof Data]
. It seems that TypeScript is unable to determine that these properties are of the same type (string or number). While there is no error if all properties are of the same type, how can I explicitly specify to TypeScript that they share the same data type?

Answer №1

It appears that utilizing composition would offer a smoother solution to circumvent the issue you are currently facing.

type Data = {
  id: number,
  name: string
}

class Person {
  data: Data

  constructor(personData: Data) {
    this.data = personData
  }

  update(updateData: Data) {
    this.data = updateData
  }
}

If there is a strong desire to access id and name as properties within a Person instance, implementing get accessors for them could be beneficial:

get id() { return this.data.id }

get name() { return this.data.name }

Playground

Answer №2

Regrettably, the only viable option seems to be making the assertion that this can be indexed by string, as shown below:

(this as {[key: string]: any})[prop] = updateData[prop as keyof Data]

Playground link

The for-in loop introduces too much dynamic behavior for static checking.


Just a friendly reminder: Specifying that updateData is of type

Data</code only guarantees it possesses the properties <code>id: number
and name: string. It does not guarantee that updateData doesn't include other unwanted properties that may get copied to your Person instance. For example, consider this call to your update method:

const somePerson = new Person({id: 1, name: "Shmoe"});
const data = {id: 2, name: "Joe", update: true};
somePerson.update(data);

This will inevitably disrupt the integrity of the Person instance. :-)

Playground link

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

React Native encountered a rendering error due to an undefined value, when an object was expected

Can someone please assist me with this strange error that I cannot figure out how to solve? Error https://i.sstatic.net/k7bd8.png https://i.sstatic.net/SIawy.png Code import React, { useRef, useState } from 'react' 2 import Animated, { Easin ...

When attempting to parse a file name using a regular expression in TypeScript (or even plain Node.js), the unexpected outcome is a

Looking to extract language information from a filename? Check out this simple construct: The structure of my language.ts model is as follows: export interface Language { language?: string; region?: string; } The function designed for parsing the fi ...

A tutorial on implementing a "Back to Top" button that appears dynamically while scrolling in Angular

I've developed a scroll-to-top feature for my Angular project, but I'm facing an issue. The scroll icon appears immediately upon page load instead of only showing after the user scrolls down. Any ideas or suggestions on how to achieve this? Here ...

Avoiding the dreaded Pyramid of Doom in Angular by utilizing rxjs .subscribe to reduce the number of nested .subscribes

I've been diving into the wonders of RxJS's .merge lately, but I thought I'd throw my question out here too because the explanations are usually top-notch. So, here's the scenario: I have a form that triggers a modal window based on us ...

Ensure that the click event on the HTML element is only triggered one time

In my application, I have the following code snippet. The issue is that this code resides in each table column header. Therefore, whenever I click on a mat-select option, new values are generated and used in an *ngFor loop for mat-option. The problem aris ...

Vercel seems to be having trouble detecting TypeScript or the "@types/react" package when deploying a Next.js project

Suddenly, my deployment of Next.js to Vercel has hit a snag after the latest update and is now giving me trouble for not having @types/react AND typescript installed. Seems like you're attempting to utilize TypeScript but are missing essential package ...

What could be causing me to consistently receive a 0 value despite my collection having content stored within it?

How can I retrieve the value of dropVolume and use it in another method after executing my getAllDropsVolumePerDate(date) function? Each time I try to access dropVolume, it returns a value of 0. dropVolume = 0; getAllDropsVolumePerDate(date: string) { ...

The .env file setting does not take precedence over the default value in the

I am facing an issue with my JSON file that contains the default convict configuration. Here is a simplified version of the file: { "env": { "doc": "The application environment.", "format": [" ...

The Angular chart is not displaying any data retrieved from the API response

I am currently experiencing a problem with plotting a ChartJs bar chart in my Angular application using data retrieved from an API response. Below is the code snippet: <div class="canvas"> <canvas id="canvas" baseChart [data ...

What is causing the error message "Module '@reduxjs/toolkit' or its type declarations are not found" to appear?

Although I have a good understanding of React-Redux, I decided to delve into TypeScript for further practice. Following the recommended approach from the react-redux team, I created a new project using the TS template: "npx degit reduxjs/redux-templa ...

Working with Angular2: Linking dropdown values with any number of items

Is there a way to dynamically bind drop down values with numbers from 1 to 100 using a loop in Angular2? I am currently using Ngprime dropdown for a limited number of values, but how can I achieve this for any number of values? Here is the template: < ...

What's the best way to refactor the `await nextEvent(element, 'mousemove')` pattern in my code once it is no longer necessary?

Within my React component, the code includes the following: class MyComponent extends React.Component { // ... trackStats = false componentDidMount() { this.monitorActivity() } componentWillUnmount() { this.trackStat ...

When utilizing makeStyles in @mui, an error may occur stating that property '' does not exist on type 'string'

I am stuck with the code below: const useStyles = makeStyles(() => ({ dialog: { root: { position: 'absolute' }, backdrop: { position: 'absolute' }, paperScrollPaper: { overflow: 'visib ...

Explore the sibling data of a specific node with the power of Firebase Cloud Functions

I am currently working with Firebase real-time database and Firebase cloud functions (using Typescript). Below is the structure of my database nodes: Orders Node: orders |- {Push ID} |--billing_id |--orders_id Shippings Node: shippings |- {Push I ...

Implement the click event binding using classes in Angular 2

If I have the template below, how can I use TypeScript to bind a click event by class? My goal is to retrieve attributes of the clicked element. <ul> <li id="1" class="selectModal">First</li> <li id="2" class="selectModal">Seco ...

Issue with inferring types in Typescript decorators

I'm encountering an issue with a TypeScript decorator related to typing function parameters in a Redux context. The decorator in question is @OnAction, which intercepts actions based on their type. My goal is to specify the type for the decorator so ...

What is the best way to simulate global variables that are declared in a separate file?

dataConfiguration.js var userData = { URIs: { APIURI: "C" }, EncryptedToken: "D" }; configSetup.js config.set({ basePath: '', files:['dataConfiguration.js' ], ..... UserComponentDetails: .....some i ...

Tips for specifying the type when utilizing the spread operator to pass props

type TypeData = { data: { id: string; class: string; name: string; country: string; ew_get_url: string; ew_post_url: string; rocket_id: string; pages: { landing: { h1: string; h2: string; } ...

Webpack is encountering difficulties in locating the entry module when working with typescript

I've been working on integrating webpack into my typescript application. To get a better understanding of webpack, I decided to do a minimal migration. I started by cloning the Angular2 quickstart seed and added a webpack.config.js: 'use strict& ...

Despite declaring a default export, the code does not include one

Software decays over time. After making a small modification to a GitHub project that was three years old, the rebuild failed due to automatic security patches. I managed to fix everything except for an issue with a default import. The specific error mess ...