Assign a true or false value to every attribute of an object

Imagine we have a scenario with an interface like this:

    interface User {
       Id: number;
       FirstName: string;
       Lastname: string;
       Age: number;
       Type: string;
    }

and a specific method for copying properties based on a flag.

    function copyIfAccepted<T extends object, K extends keyof T>(source: T, dest: T, key: K, 
  isAccepted: boolean) {
      if (isAccepted && source[key] !== dest[key]) {
        dest[key] = source[key];
      }
    }

Currently, the method is being called multiple times for each property. Keep in mind that not all properties are listed here.

     copyIfAccepted(oldUser, newUser, 'Id', true);
     copyIfAccepted(oldUser, newUser, 'FirstName', false);
     copyIfAccepted(oldUser, newUser, 'LastName', true);
     copyIfAccepted(oldUser, newUser, 'Age', true);

Is there a way to refactor this method so it only needs to be called once for all relevant properties? This should be done using TS 4.9

Answer №1

As previously stated in my comment, a helper type can be created to iterate over any type and convert it into an object with its attributes as booleans for the "isActive" part:

interface User {
  Id: number;
  FirstName: string;
  Lastname: string;
  Age: number;
}

type ToBooleanType<T> = {
  [P in keyof T]: boolean;
};

function copyIfAccepted<T extends object>(source: T, dest: T, checks: ToBooleanType<T>) {
  for (const key in source) {
    const sourceValue = source[key];
    const destValue = dest[key];
    const isAccepted = checks[key];

    if (isAccepted && sourceValue !== destValue) {
      dest[key] = sourceValue;
    }
  }
}
const user1: User = { Age: 21, FirstName: 'Joe', Id: 1, Lastname: 'Dirt' };
const user2: User = { Age: 26, FirstName: 'Jane', Id: 3, Lastname: 'Doe' };

copyIfAccepted(user1, user2, { Id: false, Age: true, FirstName: false, Lastname: true });

console.log(user1, user2);

Output:

[LOG]: {
  "Age": 21,
  "FirstName": "Joe",
  "Id": 1,
  "Lastname": "Dirt"
},  {
  "Age": 21,
  "FirstName": "Jane",
  "Id": 3,
  "Lastname": "Dirt"
} 

This code demonstrates that only the checked attributes are copied over if they are different.

Typescript Playground

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

What is the best way to retrieve a variable that has been exported from a page and access it in _

Suppose this is my pages/visitor.tsx const PageQuery = 'my query'; const Visitor = () => { return <div>Hello, World!</div>; }; export default Visitor; How can I retrieve PageQuery in _app.tsx? One approach seems to be by assi ...

Steps for accessing the camera within a custom Ionic app

Currently, I am working on a unique custom application built using Ionic and Typescript. I have encountered an issue with opening the camera to capture a picture. While my app successfully opens the native camera for capturing photos, it unfortunately tak ...

Create collaborative documents with serverless TypeScript extension

Utilizing Amazon Lambda AWS along with Serverless and the Serverless Plugin TypeScript to develop my TypeScript files has been quite a challenge. I have implemented shared code in my project, organized within folders such as: /shared: shared1.ts, shared2. ...

Is tsconfig.json necessary for JS libraries without TypeScript to include a .d.ts file when shipping?

I am currently in the process of creating a .d.ts file for an established JavaScript library that does not utilize the TypeScript compiler or include any TypeScript code. Should I include a tsconfig.json file in the library to ensure proper interpretation ...

TypeScript: By providing a variable CLASS as an argument to a function, automatically determine the return type to be an object of the specified class without any additional information

I am looking to create a function that accepts actual class objects themselves as arguments (within an object containing multiple arguments), with the return type of the function being inferred to be an instance of the class provided as the argument. In t ...

Getting a precise item in JSON with varied key signatures

Given the following JSON data: var responses = {customer : {results: 2938; id: 9283}, bredesh : {results: 2938; id: 248} }; I am trying to use an if statement in my HTML template : <div ng-if="response.(customer and bredesh and any new element (Is ...

Discovering the generic type from an optional parameter within a constructor

Looking to implement an optional parameter within a constructor, where the type is automatically determined based on the property's type. However, when no argument is provided, TypeScript defaults to the type "unknown" rather than inferring it as "und ...

Using React.ReactNode as an argument in Storybook

This is a unique button component type that I have created import React from 'react' export type ButtonProps = { label: string; color?:'primary' | 'secondary' | 'tertiary'; size?:'mobile' | 'tabl ...

Misunderstanding the concept of always being right

Here is a code snippet that raises an error in TypeScript: class Status { constructor(public content: string){} } class Visitor { private status: Status | undefined = undefined; visit(tree: Tree) { if (tree.value > 7) { this.status = new ...

Creating a dynamic TypeScript signature that includes an optional argument

For some unknown reason, I am attempting to implement a reduce method on a subclass of Map: const nah = Symbol('not-an-arg'); class MapArray<A, B> extends Map<A, B> { reduce<T = [A, B]>(f: (prev: T, next: [A, B]) => any ...

What is the best way to access the input element of ng-content from the parent component?

Creating a unique component in the following structure <div class="custom-search-field" [ngClass]="{'expanding': expanding}"> <ng-content></ng-content> </div> When using this component, users are expected to include ...

How to effectively merge DefaultTheme with styled-components in TypeScript?

I am facing an issue with integrating a module developed using styled-components that exports a theme. I want to merge this exported theme with the theme of my application. In my attempt in theme.ts, I have done the following: import { theme as idCheckThe ...

Categories for the Promise.all() function

I'm feeling lost trying to understand the differences between the request tuple return type and Promise.all(). This is driving me crazy. Any suggestions? const createPromises = async (utteranceObject: Array<string[]>): Promise<Array<[s ...

Only JSON objects with a boolean value of true will be returned

I am working on returning JSON objects in JavaScript/TypeScript that have a true boolean value for the "team" property. For example, the JSON data I am using is as follows: { "state": "Texas", "stateId": 1, "team": true }, { "state": "Cali ...

When creating utility classes, is it beneficial to offer a non-mutable API to facilitate their integration with frameworks such as React?

Currently, I am working on enhancing the functionality of my DateWithoutTime class. As part of this process, private fields within the class need to be updated by public methods. this.state.dateWithoutTimeInstance.shiftBySpecificDaysCount({ daysCount: 5, ...

Exploring the concept of relative routing within Angular

Update I made the switch from forRoot to forChild based on the responses received. Essentially, I have two issues to address. Let's consider this as a submodule: @NgModule({ imports: [ CommonModule, ARoutingModule, BModule ], decl ...

BaQend is all set to go as it initializes, just make sure to verify the user's login

Currently, I am utilizing BaQend and Ionic2 to implement certain tasks at the start of my application. 1. Database Readiness Instead of repeating this process on every page: ionViewCanEnter(): Promise<baqend> { // Verify Baqend SDK readine ...

Passing along the mouse event to the containing canvas element that utilizes chart.js

Recently, I created a custom tooltip for my chart.js chart by implementing a div that moves above the chart. While it works well, I noticed that the tooltip is capturing mouse events rather than propagating them to the parent element (the chart) for updati ...

Numerous toggle classes available

Having the following HTML inside a <span> element: <span (click)="openLeft()"></span> A method in a @Component sets a boolean variable like so: private isOpen: boolean; openLeft() { this.isOpen = !this.isOpen; } To toggle classes ...

Encountering issues when trying to import const enums in a webpack project using babel

Currently, I am working on a react project that was initially created using create-react-app. However, we later ejected and made extensive modifications to the webpack configuration. My current struggle lies in importing const enums from external libraries ...