Dynamically assign values to object properties of varying data types using indexing

My goal is to dynamically update one object using another object of the same type.

This object contains properties of different types:

type TypeOne = 'good' | 'okay';
type TypeTwo = 'default' | 'one';

interface Option {
  year: TypeOne,
  date?: TypeTwo
}

const currentData: Option = {
  year: 'good',
  date: 'default'
}

Here is the second object used to update currentData:

const newData: Option = {
  year: 'okay',
}

I have an array used to dynamically index the object:

const params: (keyof typeof currentData)[] = ['year', 'date'];

Below is the updating process where the problem arises:

params.forEach((param) => {

  currentData[param] = newData[param]  //  error: currentData[param] is inferred as type 'never' 
  
  if(param === 'year'){                 // if I would typecheck param, there would be no error
    currentData[param] = newData[param]    // But then it won't be dynamic anymore 
  }
  
});

It doesn't matter if I check if param exists in currentData, as it is already of type keyof typeof currentData.

I could check the parameter explicitly, but that would remove the dynamic aspect.

The issue seems to stem from currentData[param] being inferred as all possible values, making it uncertain when assigning a new value.

However, both currentData and newData are of the same type and are "in sync" since they use the same parameter to index both objects when assigning values. Hence, in theory, there is enough information available.

Is there a way to let TypeScript know that the objects are "synced" in this scenario?

Answer №1

If you want to make it work with your current configuration, you can utilize a type assertion to inform TypeScript that currentData[param] is indeed of type Option[param].

params.forEach((param) => {
  (currentData[param] as Option[typeof param]) = newData[param];  // works :)
});

Furthermore, if you opt for this method, it's advisable to enhance the type of your params array. This way, any inconsistencies between target objects will trigger errors. At present, if newData isn't of type Option, your forEach() will not indicate any issues, which is problematic. One potential approach is to intersect the keys of the target objects to ensure compatibility, but you have the flexibility to choose the most suitable strategy.

const params: (keyof typeof currentData & keyof typeof newData)[] = ['year', 'date']; // no error
const params: (keyof typeof currentData & keyof {random: 3})[] = ['year', 'date']; // 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

The function getServerSideProps does not return any value

I'm a beginner with Next.js and I'm currently using getServerSideProps to retrieve an array of objects. This array is fetched from a backend API by utilizing the page parameters as explained in the dynamic routes documentation: https://nextjs.org ...

The comparison between StrictNullChecks and Union Types in terms of syntax usage

Understanding StrictNullChecks in TypeScript Traditionally, null and undefined have been valid first class type citizens in JavaScript. TypeScript formerly did not enforce this, meaning you couldn't specify a variable to potentially be null or unde ...

Can you explain the purpose of this TypeScript code snippet? It declares a variable testOptions that can only be assigned one of the values "Undecided," "Yes," or "No," with a default value of "Undecided."

const testOptions: "Undecided" | "Yes" | "No" = "Undecided"; Can you explain the significance of this code snippet in typescript? How would you classify the variable testOptions? Is testOptions considered an array, string, or another d ...

Conceal or eliminate webpack from Angular 2 framework

Currently immersed in an Angular 2 project with TypeScript. Desiring to conceal or eliminate webpack from the developer tool. Came across information about uglify but it remains somewhat puzzling. See the image below for a glimpse of the Chrome Developer ...

Images are failing to render on Next.js

Hello there! I am facing an issue while working on my Next.js + TypeScript application. I need to ensure that all the images in the array passed through props are displayed. My initial approach was to pass the path and retrieve the image directly from the ...

Handling errors in nested asynchronous functions in an express.js environment

I am currently developing a microservice that sends messages to users for phone number verification. My focus is on the part of the microservice where sending a message with the correct verification code will trigger the addition of the user's phone n ...

What could be causing my NextJS application to not recognize the _document.tsx file?

Seeking assistance in understanding why my _document.tsx is not loading properly within my nextJS application. My Attempts So Far I have been diligently following the NextJS documentation for creating a custom _document.js. Despite my efforts, I am unable ...

Angular: How can the dropdown arrow in 'ng-select' be eliminated?

Is there a way to hide the dropdown arrow in an 'ng-select' element in Angular? <div class="col-md-6"> <ng-select id="selectServiceType" [items]="clientServiceTypes$ | async" pl ...

"Classes can be successfully imported in a console environment, however, they encounter issues when

Running main.js in the console using node works perfectly fine for me. However, when I attempt to run it through a browser by implementing an HTML file, I do not see anything printed to the console. Interestingly, if I remove any mentions of Vector.ts fro ...

Error: Cannot access Angular 5 Title service at this time

When attempting to change the page title using BrowserModule, I encountered an issue. I added the BrowserModule and Title in the application module as shown here: https://angular.io/guide/set-document-title However, in a child module where I tried to add ...

Removing a targeted element from an array in Angular

After receiving a JSON array object in Angular using TypeScript, I am attempting to remove a specified object from it. However, my attempts at deletion have been unsuccessful. addCategorySub(categorySub: CategorySubModel, index: number) { categorySub.id ...

registering a back button action in Ionic2 for multiple pages

Currently, I am in the process of developing my Ionic2 app and have encountered a dilemma regarding the functionality of registerBackButtonAction. On one page, let's call it pageA, I have implemented this function and everything is functioning as exp ...

React classes with external scripts

I'm currently working on embedding an external map service into my React application. The recommended way to integrate the API into a regular HTML web page is shown below: <script type="text/javascript" src="//map.search.ch/api/map.j ...

Encountering a service call error during the execution of Angular 2 unit tests using Jasmine

Struggling with testing an angular service, my TypeScript code seems correct but I keep getting an error in my test cases for "this.someFunction.show()" not being a function, even though it exists in my actual service. Here is what I'm attempting to d ...

The 'books' property cannot be found on the 'client' type

I am currently integrating the Google Book API into my project and encountering an issue while trying to add a book to a library using gapi.client. The error I keep receiving is as follows: This is the request : gapi.client.books.mylibrary.bookshelves.volu ...

Disabling the scrollbar within angular elements

Trying to remove the two scrollbars from this code, but so far unsuccessful. Attempted using overflow:hidden without success filet.component.html <mat-drawer-container class="example-container" autosize> <button type="button&qu ...

Conserving node.js native imports for Electron with rollup

I am working on a project using Electron, Svelte, and Typescript. Initially, I used a specific template from here, but it restricted access to node.js built-in imports like fs for security reasons in the browser/electron frontend. However, I do not requir ...

TypeScript integration for express-validator

Recently, I made an attempt to switch my NodeJS project with ExpressJS to TypeScript for better organization and type safety. However, I encountered an issue with the 'express-validator' middleware during this conversion process. To resolve thi ...

What are the steps to enable generators support in TypeScript 1.6 using Visual Studio Code?

I have been working with ES6 in Visual Studio Code for some time now, but when I attempt to transition to TypeScript, I encounter errors like: Generators are only available when targeting ECMAScript 6 Even though my tsconfig.json file specifies the ES6 ...

Is there a way to prevent the leaderboard from resetting each time I restart my client?

Is it possible to prevent the leaderboard from resetting every time I restart my client? You can see an example here: https://i.stack.imgur.com/2nEPw.png Please disregard the "undefined" error, I will correct it. In the current setup, the leaderboard onl ...