Exploring Variadic Tuples in Typescript

UPDATE: TypeScript 4.1 introduced this feature as mentioned by @jcalz.

I am attempting to create a generic type that can traverse a tuple. Initially, I tried using recursion but encountered an error

Type alias 'YourOperator' circularly references itself.
. Here is a basic example of my initial approach:

type VariadicAnd<T extends any[]> = T extends [infer Head, ...infer Tail] ? Head & VariadicAnd<Tail> : unknown

In my specific scenario, I also wanted to apply a transformation to the `Head` by encapsulating it within another generic type. For instance:

type SimpleTransform<T> = { wrapped: T }
type VariadicAndWithTransform<T extends any[]> = T extends [infer Head, ...infer Tail]
  ? SimpleTransform<Head> & VariadicAndWithTransform<Tail>
  : unknown;

Interestingly, while IntelliSense interprets the types correctly, the TypeScript compiler rejects it. I am considering alternative approaches or trying to find a workaround for my recursive implementation.

Answer №1

In TypeScript 4.1 and above, your code works perfectly due to the support for recursive conditional types.

type VariadicAndWithTransform<T extends any[]> = T extends [infer F, ...infer R]
  ? SimpleTransform<F> & VariadicAndWithTransform<R>
  : unknown; // no error

type Works = VariadicAndWithTransform<[{ a: 1 }, { b: 2 }, { c: 3 }]>;
/* type Works = SimpleTransform<{
    a: 1;
}> & SimpleTransform<{
    b: 2;
}> & SimpleTransform<{
    c: 3;
}> */

Prior to version 4.1, there were unofficial workarounds to allow types. To utilize recursive conditional types, make sure to update your TypeScript version.


For the desired type functionality without recursion, you can use a more efficient approach that minimizes strain on the compiler:

type VariadicAndWithTransform<T extends any[]> = {
  [K in keyof T]: (v: SimpleTransform<T[K]>) => void
}[number] extends ((v: infer I) => void) ? I : never

This method leverages inference within conditional types from unions in contravariant positions. It simplifies the process for both the compiler and the developer.

By using this non-recursive version, you can handle longer tuples without encountering errors:

type StillWorks = VariadicAndWithTransform<TwentySeven>;
/* type StillWorks = { wrapped: {}; } */    

Check out this Playground link demonstrates how it interacts with various examples.

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 steps should I take to successfully install using npm if I keep encountering the same error?

Every time I attempt to install a package using npm, I encounter the following warning: npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c7b3aeaba2b3be ...

Ways to resolve the issue: 'Error: Tether (http://github.hubspot.com/tether/) is needed for Bootstrap tooltips'

I'm encountering an issue with Bootstrap V4 where the console displays the following error message; Error: Bootstrap tooltips require Tether () Despite attempting to address this problem by installing Tether, I have been unsuccessful. I included ...

Error: The property 'getClientRects' cannot be read because it is null

I'm brand new to learning about React and I've been attempting to incorporate the example found at: Unfortunately, I've hit a roadblock and can't seem to resolve this pesky error message: TypeError: Cannot read property 'getClient ...

Having difficulty entering text into a "Search Input Field" that is a react component in testcafe

Struggling to input text in a "Type to search dropdown" that is a react component. While able to click on the component, typing any text seems to be an issue. Listed below is an example of the code: import { Selector } from 'testcafe'; test(&ap ...

JavaScript: choosing between assigning to the callback function or using an anonymous function

MY CONCERN I have been exploring AJAX fundamentals from various online sources. While grasping the multi-step process of sending an asynchronous HTTP request, I noticed a slight discrepancy in the way the usage of the .onload property is handled on the XH ...

Problem with Resetting State in Cordova/AngularJS

Currently, I am facing a challenge with my Cordova/AngularJS mobile application as I struggle to refresh the current state with new data. Please be aware that this is not an Ionic Framework application. The issue arises in the part of my app where I need ...

Preventing default behavior in Firefox using jQuery with event.preventDefault()

Having encountered issues with event.preventDefault() specifically in Firefox, I noticed that the jQuery code included below is not functioning as intended. $("#facebook-del-1").click(function(){ event.preventDefault(); var selector = "#"+$(this).attr("id ...

Error message: Unable to interact with element due to visibility issue

Is there a way to click on a radio button that appears on a webpage? Below is the code snippet: HTML code: <div class="small-checkbox red-theme raleway-regular text-muted2 position-relative"> <div class="city-checkbox inline-block posit ...

Ways to run a javascript command just a single time

I have a function that makes an HTTP GET request to compare a given value with elements in an array. If there's no match, I want to add the value to another array. The issue is that duplicates are being added to the array because of multiple loop iter ...

Utilizing regular expressions for querying MongoDB

Attempting to retrieve data from MongoDB by querying for a specific field name using regular expressions. For example, if the constant name is set as 'st', the expected result would be 'steven', 'stephanie', and 'stella&a ...

Encountering this error for the first time - Uncaught Error displayed in the Console

I have been working on a ToDo list and it is almost complete. However, I have encountered an unfamiliar error in the console that is preventing me from creating the list. The error message reads as follows: OPTIONS http://localhost:4000/cpds/add net::E ...

Is it necessary to delay until the entire page finishes loading in Selenium 3?

public boolean CheckPageLoadStatus(){ final ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() { public Boolean apply(final WebDriver driver) { return ((JavascriptExecutor) driver).executeScr ...

What methods does YepNope.js offer for assigning dynamic names to scripts?

Currently, I am utilizing YepNope.js to handle the loading of my css and javascript files. My query is regarding whether there is a method to assign variable names to these scripts during the initial process. For example: yepnope({ test : Modernizr.cs ...

HTML Form Validation - Conditional implementation based on radio button choice

My HTML form utilizes the JQuery Validate plugin to enforce mandatory fields. One of the form fields is a radio button with three options: Hours Days Unsure Another field requires the user to enter a number corresponding to their selection of "Hours" or ...

Enable/disable specific dates in datepicker depending on dropdown selection

Struggling with disabling specific days of the week in the jQuery datepicker based on a selected dropdown option. Provided below is the snippet of my HTML and JavaScript code: <script> $("#dates").datepicker({ minDate: 0 }); </sc ...

Utilize Javascript to locate the image width and assign it to the wrapper divs in WordPress

I am trying to figure out how to set the wrapper divs' widths equal to the size of the images (featured images) they contain so that they are evenly spaced from each other. I came across a potential solution here: (solution at the bottom), but I am ...

Performing a Search Operation using AJAX with Elasticsearch

I've been struggling to find the correct method for requesting data from elasticsearch using a jQuery AJAX call. I keep encountering parsing errors or getting all documents in the index instead of my intended results. $(document).ready(function() ...

Tips for adjusting text color in a paragraph based on its content

I have a paragraph or h1 with phrases like "the color of this item is Magenta" or "this output is Red". These color-specific words (red, black, cyan, magenta or yellow) may appear within the paragraph or h1 tag. Here is my current code snippet: HTML < ...

Each Jest test file should have a specified window.location

After upgrading to Jest 22, I encountered an issue with mocking window.location. Previously, this method worked fine but stopped working after the update. Object.defineProperty(window.location, 'href', { writable: true, value: 'http ...

Developing ES6 modules in C++ using Node.js

Here is a previous example showcasing how to create a Node.js addon in C++: https://nodejs.org/api/addons.html You can use node-gyp to build it into a common JS module, which works well with the 'require' function. However, when trying to impo ...