What is a secure method for detecting variances between two objects in TypeScript?

I have two objects with similar properties. I want to compare the values of each property in both objects and find the differences.

The following code is functional but generates TypeScript errors:

export type Item = {
  name?: string;
  age?: number;
  location?: {
    x: number,
    y: number
  }
};

const item1: Item = { name: "Jim", age: 32, location: {x: 1, y: 2} };
const item2: Item = { name: "Jim" };

const itemDiff: Item = {};

Object.entries(item1).forEach(([key, value]) => {
  if (item1[key] !== item2[key]) {
    itemDiff[key] = value;
  }
});

An 'any' type error occurs because a 'string' expression cannot index type 'Item'. No signature using 'string' found in type 'Item'.ts(7053)

To reduce the errors, I utilized the ts-extras library:

objectEntries(item1).forEach(([key, value]) => {
  if (item1[key] !== item2[key]) {
    itemDiff[key] = value;
  }
});

However, I still encounter an error at itemDiff[key] = value;:

(parameter) key: keyof Item Type 'string | number | { x: number; y: number; } | undefined' is not assignable to type 'undefined'. Type 'string' is not assignable to type 'undefined'.ts(2322)

Answer №1

Include an intersection to enforce that keys of Thing must be strings:

type Thing = {
  name?: string;
  age?: number;
  location?: {
    x: number,
    y: number
  }
} & { [key: string]: any };

Answer №2

To achieve this result, you can utilize the power of Partial Types:

type Item = {
  name?: string;
  price?: number;
  category?: {
    type: string;
    subcategory: string;
  };
};

const items: Item = { name: 'Shoes', price: 50, category: { type: 'Footwear', subcategory: 'Casual' } };
const items2: Item = { name: 'Shoes' };

const filteredItems = {} as Partial<Record<keyof Item, any>>;

Object.entries(items).forEach(([key, value]) => {
  const itemKey = key as keyof Item;

  if (items[itemKey] !== items2[itemKey]) {
    filteredItems[itemKey] = value as Item[keyof Item];
  }
});

Partial<Item> allows you to make properties optional while ensuring type safety. By casting key as keyof Item, you validate its existence in the object. Similarly, by casting value as Item[keyof Item], TypeScript understands it belongs to Item.

The output will look like this:

{ price: 50, category: { type: 'Footwear', subcategory: 'Casual' } }

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

Using TypeScript: Defining function overloads with a choice of either a string or a custom object as argument

I'm attempting to implement function overloading in TypeScript. Below is the code snippet I have: /** * Returns a 400 Bad Request error. * * @returns A response with the 400 status code and a message. */ export function badRequest(): TypedRespons ...

Express middleware generator function causing a type error

I recently implemented a function that takes a middleware function, wraps it in a try-catch block, and then returns the modified middleware function. tryCatch.ts import { Request, Response, NextFunction } from "express"; export default function ...

connecting models with sequelize-typescript

I'm currently working on establishing the following relationships: User is associated with one Account User is linked to one Application Application has multiple Members The issue I'm encountering is that when the models are generated, the acco ...

Problem with Typescript and packages.json file in Ionic 3 due to "rxjs" issue

I encountered a series of errors in my Ionic 3 project after running ionic serve -l in the command terminal. The errors are detailed in the following image: Errors in picture: https://i.sstatic.net/h3d1N.jpg Full errors text: Typescript Error ';& ...

When incorporating pinia with Vue, encountering an error with the decorator that says "Error: Unable to access 'useCoreStore' before initialization" may happen

While implementing the vue-facing decorator in my current project, I encountered an issue with setting up pinia. The structure of my component resembles the example provided here: I have verified that decorators like @Setup are functioning correctly, ind ...

Error TS2345: The function with arguments of type '(req: any, res: any, ctx: any) => any' cannot be assigned to the parameter of type 'HttpResponseResolver<PathParams<string>'

Encountered an issue in a React TypeScript test case involving mock data. The error message received was: TS2345: Argument of type '(req: any, res: any, ctx: any) => any' is not assignable to parameter of type 'HttpResponseResolver<P ...

What is the best way to interact with the member variables and methods within the VideoJs function in an Angular 2 project

Having an issue with accessing values and methods in the videojs plugin within my Angular project. When the component initializes, the values are showing as undefined. I've tried calling the videojs method in ngAfterViewInit as well, but still not get ...

Context API is failing to work in components that use children when the version is v16.6.0 or higher

Currently, I am utilizing the latest context API of React (v16.6.0 or higher) by specifying the public static contextType inside the component that consumes the context. Everything works smoothly unless the component declaring the Provider directly include ...

Can you tell me the equivalent in Angular of the hasClass method?

Looking to target elements with a designated class and dynamically update their contents ...

Tips for effectively managing TypeScript values with various types

I am currently facing an issue with the TS interface shown below: export interface Item { product: string | Product; } When I try to iterate through an array of items, I need to handle the type checking. For example: items = Items[]; items.forEach(ite ...

Sinon made it difficult to successfully stub/mock a method return

I find myself facing a challenge as I navigate the learning path to nodejs and explore advanced javascript features. Progress is slow but steady. One of the rest endpoints utilizes the (azure blob storage) method from containerclient, which requires conver ...

Revamping elements according to ordered array. Angular version 4.3

Dealing with an array of data that needs to be sorted for displaying in a component seems to be a challenge. Despite having a functional code sample demonstrating the concept, the sorting is not reflected in the Angular app's DOM. The original data i ...

What could be causing the Intellisense errors in Visual Studio 2015 that say "Cannot find module 'angular2/core'"?

Currently, I am utilizing Visual Studio 2015 Update 1 in conjunction with TypeScript 1.8.5. Within my ASP.NET MVC 4.6 Web Application, Angular2 is being used. The TypeScript compile options have been configured with the following settings: <PropertyG ...

Tips for adjusting HighCharts layout with highcharts-vue integrations

I have a fairly simple component: <template> <div> <chart v-if="!loading" ref="priceGraph" constructor-type="stockChart" :options="chartData" ...

When embedding HTML inside an Angular 2 component, it does not render properly

Currently, I am utilizing a service to dynamically alter the content within my header based on the specific page being visited. However, I have encountered an issue where any HTML code placed within my component does not render in the browser as expected ( ...

Declaring Objects and Relationships in Angular Models

Wondering if it's possible to declare an object inside my model. First attempt: export class Employee{ emp_id: number; emp_fname: string; emp_lname: string; emp_birth: string; emp_status: string; emp_photo: string; emp_dep ...

Is there a more effective way to implement a Custom Validator using .forEach?

I have developed my own validation class as a learning exercise. Do you think this is an effective approach, or do you have suggestions for improvement? import { AbstractControl } from '@angular/forms'; export class ProjectNameValidator { pr ...

Utilizing Typescript and RequireJS for Incorporating jqueryui

Recently, I've been encountering issues with getting jQueryUI to function properly. Strangely enough, prior to attempting to integrate jQueryUI, using jQuery alone worked perfectly fine. The current problem I'm facing is receiving a "TypeError: ...

Using Angular's *ngIf directive to switch between three classes

I am working with a div in Angular and I am looking to switch between 3 classes. My HTML code looks like this: <div *ngIf="status">Content Here</div> In my .ts file, I have defined a variable: status = 'closed'; The statu ...

Property missing in Typescript type definition

In my Typescript Next project, I am using this component: import PageTitle from './pagetitle' import style from './contact.styl' export default function Contact() { return ( <section> <a name="contact"> ...