Determine the data type of sibling attributes by analyzing the types of other siblings

I am in the process of creating a simple abstraction that displays patches to an object.

type MyObject = {
  attributeA: string;
  attributeB: boolean;
  attributeC: number;
};
type MyObjectKeys = keyof MyObject;

type Difference<Key extends MyObjectKeys = MyObjectKeys> = {
  // The value of this attribute should determine
  // the type of the old and new value.
  key: Key;
  oldValue: MyObject[Key];
  newValue: MyObject[Key];
};

type Patch = {
  patches: Difference[];
};

const patch: Patch = {
  patches: [
    {
      key: 'attributeB',
      // Should be inferred as boolean.
      oldValue: '',
      // Both should have the same inferred type.
      newValue: 9,
    },
  ],
};

I am aiming for oldValue and newValue to be typed based on the provided key. Regrettably, as mentioned in the code comments, it is not functioning correctly.

I appreciate any guidance!

Answer №1

It's important to understand that type inference operates differently in this context. To simplify the process, consider creating some auxiliary functions:

type MyObject = {
  attributeA: string;
  attributeB: boolean;
  attributeC: number;
};
type MyObjectKeys = keyof MyObject;

type Difference<Key extends MyObjectKeys = MyObjectKeys> = {
  // The type of old and new values should be determined by this attribute.
  key: Key;
  oldValue: MyObject[Key];
  newValue: MyObject[Key];
};

type Patch = {
  patches: Difference[];
};

function createPatch<T extends MyObjectKeys>(key: T, oldValue: MyObject[T], newValue: MyObject[T]): Difference<T> {
    return {
        key,
        oldValue,
        newValue,
    };
}

function addPatch<T extends MyObjectKeys>(key: T, oldValue: MyObject[T], newValue: MyObject[T], patch: Patch) {
    patch.patches.push(createPatch(key, oldValue, newValue));
}

const patch: Patch = {
  patches: [createPatch('attributeB', '', 9), createPatch('attributeA', '', 'newVal')],
};

addPatch('attributeC', 0, 10, patch);

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

Promise rejection not handled: The play() function was unsuccessful as it requires the user to interact with the document beforehand

After upgrading my application from Angular 10 to 11, I encountered an error while running unit tests. The error causes the tests to terminate, but strangely, sometimes they run without any issues. Does anyone have suggestions on how to resolve this issue? ...

Transform a flat JSON string into a hierarchical structure by organizing it by parent ID

I am currently working on implementing a Mat-Tree using Angular Material. The data I have is in the form of a flat JSON string: "Entity": [ { "ID": 1, "NAME": "Reports", "PARENTID": "0", "ISACTIVE": "Y", "CREATIONDATE": "20 ...

What is the method for specifying the type of a function itself?

Imagine a scenario where a function is designed to accept other functions as arguments: Metric = Callable[List[float], float] def metric_doubler(metric: Metric, lst: List[float]): return 2*metric(lst) Now, if there is a need to define multiple functi ...

Creating a personalized NPM package: Converting and exporting TypeScript definitions

Question: Do I need to adjust my TS configuration or add a TS build step? I recently developed a new npm package: Custom-NPM-Package / - src -- index.js -- index.d.ts -- IType.ts accompanied by this tsconfig.json: { "compilerOptions" ...

How can you define a generic type alias in TypeScript for a function that is also generic?

I am facing a challenge with creating a generic alias for a typed generic function. Despite my efforts, I have not been successful in achieving this. Here is an example of what I'm encountering: // foo.tsx function foo<T>(arg: T): T { return a ...

Is there a way to mark a template-driven form as invalid when a custom field validator fails in my Angular 15 application?

Currently, I am working on an Angular 15 app that utilizes a hand-coded JSON file along with the JSON server for performing CRUD operations on a "employees" JSON data. One of the tasks at hand involves adding custom validation to a <select> element. ...

Step-by-step guide to configuring Angular 2 in Visual Studio 2013

Struggling to set up Angular 2 in Visual Studio 2013 without any external web tools? Even after following the Angular2 Quick Start guide, I couldn't get it to work. Is tsconfig.json supported in VS 2013? Any assistance or helpful links would be grea ...

Merging RXJS observable outputs into a single result

In my database, I have two nodes set up: users: {user1: {uid: 'user1', name: "John"}, user2: {uid: 'user2', name: "Mario"}} homework: {user1: {homeworkAnswer: "Sample answer"}} Some users may or may not have homework assigned to them. ...

Develop a fresh Typescript-driven sql.js database

I'm in the process of converting my JavaScript code to TypeScript. One of the libraries I rely on is sql.js. I have successfully installed the corresponding typing for it, but I am facing a roadblock when it comes to creating the database. Here is ho ...

Error: Local variable remains undefined following an HTTP request

Whenever I make http calls, my goal is to store the received JSON data in a local variable within my component and then showcase it in the view. Service: getCases(){ return this.http.get('someUrl') .map((res: Response) => res.jso ...

The react decorator for maintaining type safety fails to identify the appropriate ReturnType of the supplied function

I want to enhance the redux connect feature by using it as a decorator for a specific reducer/state. Although I know that redux connect can already be used as a decorator, I am curious about why my custom implementation does not work the way I expect. Her ...

Transform Object Properties into an Object Array

When calling an authentication API, I receive an Observable<any> with the following object: name: "John" role: "Admin" The response may vary in a few ways: Extra fields could be included; If a field has multiple values, it ...

I am experiencing issues with my HTML select list not functioning properly when utilizing a POST service

When using Angularjs to automatically populate a list with *ngFor and then implementing a POST service, the list stops functioning properly and only displays the default option. <select id="descripSel" (change)="selectDescrip()" > <option >S ...

When the first element of an array is undefined, Angular's ngFor will not render anything

We have an array called stringArray: var stringArray = new Array(); stringArray[1] = 'one'; In Angular, the ngFor directive displays nothing when stringArray[0] is undefined. How can this issue be resolved? ...

Leveraging AnimatePresence from the Framer Motion library to design an exit animation for a motion.div

My goal is to implement a side menu that smoothly slides in and out when the menu/close button is clicked using framer motion. Initially, clicking on the menu button will cause the menu to slide out from the left side of the screen while changing the butto ...

Creating a State in Typescript Vuex with Accessors: A Step-by-Step Guide

Within the vuex store, I am attempting to initialize a state called _token. However, when I try to access the property within the same class, I am encountering an error message stating that the setter for _token is not defined. Can anyone shed light on why ...

Is there a way to define an interface that consists of child objects as the type for a function that uses destructured props?

Is there an alternative to this method? import { client } from "./setupApi"; export const getLayout = ({ page, entity, list }: {page: string, entity: string, list: string}) => { return client.get("/secure/nav.json"); }; How do I ...

Using Two Unique Typeface Options in Material UI for ReactJS

Currently, in my React App, I am utilizing the Material UI library with Typescript instead of regular Javascript. I've encountered a small hurdle that I can't seem to overcome. The two typefaces I want to incorporate into my app are: Circular-S ...

React TypeScript throws an error when a Socket.IO object is passed to a child component and appears as undefined

Currently, I'm developing a simple chat application as part of my university course. The code below represents a work-in-progress page for this project. While I am able to get the socket from the server and use it in the main component without any is ...

Types that depend on function input parameters

I am facing a challenge with a function: function navigateOptions(currentScreenRoute: 'addGroup' | 'addGroupOnboarding', group: GroupEngagement) { const navigationKey = currentScreenRoute === 'addGroup' ? 'addGroupPeopl ...