What is the best way to maintain the order of variadic types for conditionally inferred conditional types?

Here is the type definition that I am working with:

type Inner<Type> = Type extends Wrapper<infer U>[] ? U[] : never;

Additionally, I have a function with the following signature:

function myFunc<From extends Wrapper[], To>(
    values: From,
    transform: (v: Inner<From>) => To
)

When I provide a callback as the transform argument, the argument list inferred for that callback becomes an array of union types instead of preserving the original order.

For example, if the values array is

[Wrapper<number>, Wrapper<string>]
, then the arguments inferred for transform would be (number|string)[] (without maintaining the order), when I intended it to be [number, string].

Is there any way to retain the order in this scenario?

*Edit For the purpose of this discussion, you can assume that Wrapper is defined as type Wrapper<T> = {x:T}

Answer №1

To provide a comprehensive explanation, it's essential to include a minimal reproducible example in the initial question. In the absence of that, the assumption is made that there is a structural dependency of Wrapper<T> on T, with a default that tends to be unrestricted like any:

type Wrapper<T = any> = { x: T };

The best approach would be to make Inner a mapped type, as this automatically handles the mapping of arrays to arrays and tuples to tuples:

type Inner<T extends Wrapper[]> =
    { [K in keyof T]: T[K] extends Wrapper<infer U> ? U : never };

With this setup, your myFunc() should function more or less as you intended:

declare function myFunc<W extends Wrapper[], T>(
    values: [...W],
    transform: (v: Inner<W>) => T
): void;

By changing the type of values to [...W], a variadic tuple type, the compiler is guided to infer values as a tuple when applicable, ensuring that the benefit from the mapped type is retained.


An example test could involve the following scenario that aligns with your query:

declare const wn: Wrapper<number>;
declare const ws: Wrapper<string>;

myFunc([wn, ws], v => v[1].length < v[0])
// (parameter) v: [number, string]
// function myFunc<[Wrapper<number>, Wrapper<string>], boolean>

Upon testing, it appears to work correctly. IntelliSense confirms that values is interpreted as

[Wrapper<number>, Wrapper<string>]
, leading to the inference of v as [number, string], aligning with expectations.

Link to code 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

Expandable Grid Sections in React MUI

Is there a way to create a grid layout where items with showDefault: true are always displayed at the top, and then users can click an arrow button to expand the grid and also show the items with showDefault: false? Any suggestions on how to achieve this? ...

Tips for formatting dates in Angular 6

I am currently working on a function that displays real-time dates based on user input. Currently, when the user enters the input, it is displayed in the front end as follows: 28.10.2018 10:09 However, I would like the date to change dynamically based on ...

Updating the value of a key in an object is not functioning as expected

There is a single object defined as requestObject: any = { "type": 'type1', "start": 0, "size": 10, "keywords": ['abcd','efgh'], filters: [], } Next, attempting to change the value for keyword, I updat ...

I am attempting to send an array as parameters in an httpservice request, but the parameters are being evaluated as an empty array

Trying to upload multiple images involves converting the image into a base64 encoded string and storing its metadata with an array. The reference to the image path is stored in the database, so the functionality is written in the backend for insertion. Ho ...

Angular 2 file upload encountering CORS issue leading to 401 unauthorized error

Encountered a "401 Unauthorized" error in Chrome and Firefox while attempting to upload files using angular 2 CLI to an apache2-server with a PHP backend. Despite trying three different node modules, the issue persists from the OPTIONS-preflight stage, ...

Angular 7 router navigate encountering a matching issue

I created a router module with the following configuration: RouterModule.forRoot([ {path: 'general', component: MapComponent}, {path: 'general/:id', component: MapComponent}, {path: '', component: LoginComponent} ]) Sub ...

Receiving NULL data from client side to server side in Angular 2 + Spring application

I'm currently working on a project that involves using Angular 2 on the client side and Spring on the server side. I need to send user input data from the client to the server and receive a response back. However, I'm encountering an issue where ...

Error: The variable _ is undefined when trying to use the .map() function on an array

While working on my project, I encountered a "ReferenceError: _ is not defined" when using the .map function in this code snippet: arr.map(async (elem) => { ... }); I couldn't find any explicit mention of "_" in my code. The error trace pointed me ...

AngularTS regex that enforces the use of a decimal point in numbers

I am working on a requirement where the input should only accept decimal characters, negative or positive. I need to use regex to make the decimal point mandatory, however it is currently allowing negative whole numbers which is not the desired behavior. I ...

What is the best way to incorporate an AJAX GET request into an HTML element?

Currently, I am attempting to execute a JavaScript code that will convert all <a></a> elements found within another element <b></b> (the specific name in the HTML) into links that trigger an HTTP get request. However, the code I hav ...

What are the best strategies to troubleshoot issues during NPM Install?

I keep encountering errors during the npm install process, but everything works fine when I use npm install --force in my local environment. However, the issues persist during the repository build as my .yaml file script contains "npm install". Can anyone ...

The data type 'number' cannot be assigned to the data type 'undefined'. Error code: ts(2322)

I encountered an issue where it's giving me an error stating that type number cannot be assigned to type undefined on the last digit (1) in scale={[1.618, 1, 1]}. Can anyone help me figure out how to resolve this TypeScript error? "use client&quo ...

Having trouble uploading a PNG image (logo) with Cypress

I have been attempting to upload a png file using Cypress and here is what I have tried so far: Cypress.Commands.add('upload_image', (fileName, selector) => { return cy.get(selector).then(subject => { return cy.fixture(fileName, &apo ...

What is the best way to change the `this` type of an object that is provided as a parameter to a function

I am looking to create a custom function that can expose certain properties to the this of an object being passed as an argument. For example, this is how the function would be called: const props = ['bar']; myBarFunction(props, { get foo() { ...

Using getters in a template can activate the Angular change detection cycle

When using getters inside templates, it seems that Angular's change detection can get stuck in a loop with the getter being called multiple times. Despite researching similar issues, I have not been able to find a clear solution. Background info: I ...

What causes the discrepancy in results between these two NodeJS/Typescript imports?

Within my NodeJS project, I have integrated typescript version 3.2 alongside express version 4.16 and @types/express version 4.16. My development is focused on using Typescript with the intention of transpiling it later on. The guidelines for @types/expre ...

Issue: An error occurred while trying to parse JSON data in TypeScript due to an undefined 'description' property

Encountering an error message when attempting to retrieve the description attribute from the following Sample Json. Error: TypeError: Cannot read property 'description' of undefined when trying to access json data in typescript import {Age ...

ngOnChanges will not be triggered if a property is set directly

I utilized the modal feature from ng-bootstrap library Within my parent component, I utilized modalService to trigger the modal, and data was passed to the modal using componentInstance. In the modal component, I attempted to retrieve the sent data using ...

Implement a new functionality to a publicly accessible type without violating the pre-established agreement

I'm looking to enhance an existing exported type with a new method, without causing any disruption to the current usage in production. import * as BunyanLogger from 'bunyan'; import init from './logger'; export type Logger = Bunya ...

Should one bother utilizing Promise.all within the context of a TypeORM transaction?

Using TypeORM to perform two operations in a single transaction with no specified order. Will utilizing Promise.all result in faster processing, or do the commands wait internally regardless? Is there any discernible difference in efficiency between the t ...