The second generic argument's inference is not limited

Seeking assistance in creating a function that allows for specifying objects which extend the type

Record<string, Record<string, number>>
, along with default values for certain properties within those objects.

For instance, given specific inputs, I need to define types that will later be used in the return value:

[ { obj: { test: { a: 1, b: 2 } }, defaults: {} } ] ---> { test: "a" | "b" }
[ { obj: { test: { a: 1, b: 2 } }, defaults: { test: "b" } } ] ---> { test?: "a" | "b" }
[
  { obj: { test: { a: 1, b: 2 } }, defaults: {} },
  { obj: { test2: { a: 2, d: 5 } }, defaults: { test2: "a" } }
] ---> { test: "a" | "b", test2?: "a" | "d" }

Essentially, if default values are specified for certain properties within an object, those properties should become optional in the resulting type.

The challenge lies in getting TypeScript to accurately infer the type for the second argument. The goal is to correctly infer the input type in order to construct it later:

type Idx<T, K> = K extends keyof T ? T[K] : never

const g = <
    Objs extends Record<string, Record<string, number>>[],
    Defaults extends { [I in keyof Objs]: { [K in keyof Objs[I]]: keyof Objs[I][K] } }
>(...props: 
    { [I in keyof Objs]: { obj: Objs[I], defaults: Idx<Defaults, I> } } &
    { [I in keyof Defaults]: { obj: Idx<Objs, I>, defaults: Defaults[I] } }
) => {}

g({
    obj: { test: { a: 1, b:2 } },
    defaults: {  }
})

This piece of code does not compile as expected because Defaults is inferred as

[{test: "a" | "b" }]
rather than [{}]. It draws inspiration from this answer.

It seems there may be a simple error in defining the Defaults type, but I'm struggling to resolve it.

Answer №1

For those who wish to exclude properties from the default values (allowing `{}` instead of `{test: "b"}`), it is necessary to ensure that the elements in `Defaults` act like a Partial type and use the optional modifier `?` when mapping their keys:

Defaults extends { [I in keyof Objs]:
    { [K in keyof Objs[I]]?: keyof Objs[I][K] }
}

By doing this, everything should function as expected:

g({ obj: { test: { a: 1, b: 2 } }, defaults: {} }); // works fine
// const g: <[{ test: { a: number; b: number; };}], [{}]>

Link to Playground for code testing

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

complete() method is not triggered by Observable

Note: I understand that there is a timer observable from rxjs, but for the purpose of this project, I am using it as a proof of concept to enhance my understanding of observables. In my Angular application, I have developed a timer with a start button, a ...

Having trouble updating an array of objects using setState in Typescript

As a TypeScript novice, I am currently learning how to update the state of an array containing objects. The array in question is as follows: const [quantity, setQuantity] = React.useState<any[]>([ { id: '1', q: 100, }, ...

TypeScript Library encounters issues when importing a specific data type

I recently integrated a library into my Next.js application to manage layouts using useState in react-grid-layout. To make this work with TypeScript, I had to install the necessary package shown below: npm install --save @types/react-grid-layout The code ...

Tips for sending TypeScript objects to Vue components

Currently, I am working with the Vue 2 composition API plugin along with typescript version 3.9.7. In my project, I have a simple type defined as Usp which I want to pass as a prop to a component named UspSection. The structure of the USP type is outline ...

Having trouble opening a modal view from an action sheet button

Currently, I am in the process of working on a school project and facing an issue where I am trying to open a modal view from an action-sheet button. However, I encounter the following error message: TypeError: Cannot read property 'addMedicationModal ...

Unauthorized Token Authentication in .NET and Angular Application

Encountering an issue with user authentication. Login is successful and I receive a token from the API, which I save in JwtTokenService within my Angular App. When making a request (e.g. Delete), I add the "Authorization" header with the value "Bearer toke ...

Setting options using the form group in dropdowns in Angular can greatly enhance the user experience

I have created a FormGroup called holidayform and set it up as follows: holidayform: FormGroup; this.holidayform = this.fb.group({ title: ['', [Validators.required]], entryDate: ['',], }) this.holidayform.patchValue ...

Creating a versatile TypeScript Record that can accommodate multiple data types

I have a question regarding the use of Record in TypeScript. When I specify Record as the parameter type in a function, I encounter an error in my code because it does not allow different types. type Keys = 'name' | 'qty'; const getVal ...

Leveraging TypeScript for defining intricate tree manipulation guidelines

In my current project, I am working on enhancing a TypeScript process that is in place. The goal is to make it more strongly typed for better scalability and accuracy. The structure of the existing tree under consideration is as follows: interface Node { ...

What are the steps for performing projection in TypeScript?

Looking to fill up the orders array, which consists of objects of type Order. The desired output is orders=[{id:1,qt:4},{id:2, qt:2},{id:3,qt:2}]. How can I achieve this using TypeScript? I am new to this language. export class Product { constructor(publ ...

Combining React, Typescript, and asynchronous Promises

Currently I am in the process of developing a component that interacts with a webservice to fetch data asynchronously using promises. Once the promise is fulfilled, I intend to integrate the results into my component's rendering method. My ultimate go ...

What is the process for converting TSX files into JSX format?

Recently, I completed a project using Expo and TypeScript due to my familiarity with type-safe languages. However, now I need to convert the code to Expo written in JavaScript. While I could manually remove the types as I work through it, I am curious if ...

I am having trouble locating my source code within the Typescript module

My issue lies with a file called Server.js, which holds the code for export class Program and includes <reference path='mscorlib.ts'/>. However, when I compile it using the command: tsc -t ES5 Server.ts --module commonjs --out Server.js T ...

Using TypeScript in Angular to make a function call can result in an endless loop being created

In my current use case, I am aiming to update the array in both the if and else scenarios. The primary array, referred to as cis, appears as follows: https://i.sstatic.net/esbb8.png .html <sample-container [cis]="filterCi(currentBaseline.cis, c ...

Angular-Slickgrid: Some filters may not display on the header row

After thorough investigation and experimentation, I was able to identify both the issue and a suitable solution: The problem stemmed from our dataset's usage of numeric IDs (e.g. 1,2,3,...). Within the code, there was an error where the grid misinter ...

Potential explanation for unexpected Typescript initialization error

I am encountering the compiler error The property 'options' is not initialized or assigned in the constructor. However, upon reviewing the code for the respective class, it is clear that this reported error does not accurately reflect the actual ...

The absence of defined exports in TypeScript has presented a challenge, despite attempting various improvement methods

I've exhausted all available resources on the web regarding the TypeScript export issues, but none seem to resolve the problem. Watching a tutorial on YouTube, the presenter faced no such obstacles as I am encountering now. After updating the tsconf ...

Using TypeScript will result in errors when attempting to use the Promise object and the Awaited keyword

In this example, I am trying to ensure that the function foo does not accept a Promise as an argument, but any other type should be acceptable. export {} function foo<T>(arg: T extends Promise<unknown> ? never : T) { console.log(arg); } asy ...

The Typescript compiler is unable to ignore imported JavaScript files

Recently, I started working with TypeScript and Angular 2, but encountered a problem that has left me puzzled. Initially, everything was going smoothly with the angular2 quickstart project until I attempted to import a plain JavaScript file. import * as m ...

What is the best way to extract values from a specific table column and store them in an array using Angular?

I have a section of code containing a table in my component: expect-next-month.component.html <table id="users"> <tr> <th>Number of month</th> <th>Total checking e ...