What is the process for obtaining a flattened tuple type from a tuple comprised of nested tuples?

Suppose I have a tuple comprised of additional tuples:

type Data = [[3,5,7], [4,9], [0,1,10,9]];

I am looking to develop a utility type called Merge<T> in such a way that Merge<Data> outputs:

type MergedData = Merge<Data>;
// type MergedData = [3,5,7,4,9,0,1,10,9];

For this scenario, it is safe to assume that the tuples are only nested one level deep. The size of the tuples can vary.

What would be the best approach to achieve this?

Answer №1

If you want to achieve this, you would need recursive conditional types. This feature will be fully available in version 4.1.

type Example = [[3,5,7], [4,9], [0,1,10,9]];
type Flatten<T extends any[]> = 
    T extends [infer U, ...infer R] ? U extends any[] ? [...U, ... Flatten<R>]: []: []
type FlatExample = Flatten<Example>;

Playground Link

Edit

A simpler version, courtesy of jcalz:

type Example = [[3,5,7], [4,9], [0,1,10,9]];
type Flatten<T extends any[]> = 
    T extends [any, ...infer R] ? [...T[0], ... Flatten<R>]:  []
type FlatExample = Flatten<Example>;

Playground Link

/Edit

You can implement a workaround even now (the extra level of indirection is necessary to trick the compiler into accepting the recursive conditional type; conceptually, it is similar to the simplified version above):

type Example = [[3, 5, 7], [4, 9], [0, 1, 10, 9]];
type Flatten<T extends any[]> = T extends [infer U, ...infer R] ? {
    1: U extends any[] ? [...U, ...Flatten<R>] : [],
    2: []
}[U extends any[] ? 1 : 2] : [];

type FlatExample = Flatten<Example>;

Playground Link

Just for fun, here's the generalized flattening version for 4.1.

type Example = [[3,5,7], [4,9, [10, 12, [10, 12]]], [0,1,10,9, [10, 12]]];
type Flatten<T extends any[]> = 
    T extends [infer U, ...infer R] ? 
        U extends any[] ? 
        [...Flatten<U>, ... Flatten<R>]: [U, ... Flatten<R>]: []
type FlatExample = Flatten<Example>;

Playground Link

Note: Although recursive types are more supported in 4.1, keep in mind that you may still encounter hardcoded limits in the compiler, such as type instantiation depth and total type instances. Recursive types tend to generate a large number of type instantiations, so use them judiciously.

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

The operation to assign a value to property 'two' cannot be completed as it is currently undefined

I'm facing an issue with the code below and cannot figure out why I am encountering the error message. I have ensured that each object contains a value, so why is there a reference to 'undefined'? Cannot set property 'two' of unde ...

Form validation is an essential feature of the Angular2 template-driven sub form component

I'm currently working on a template-driven form that includes a group of inputs generated through an ngFor. My goal is to separate this repeating 'sub-group' into its own child component. However, I'm encountering difficulties in ensur ...

What is the reason behind eslint not permitting the rule option @typescript-eslint/consistent-type-imports?

Upon implementing the eslint rule, I configured it like this. module.exports = { rules: { "@typescript-eslint/consistent-type-imports": [ "error", { fixStyle: "inline-type-imports" ...

Mastering the Art of Injecting Objects from the Server

Utilizing Angular Universal, I am serving my Angular application through an Express server. The objective is to embed an environment object (from the server) into my application. To achieve this, I have created an InjectionToken export const ENVIRONMENT ...

Retrieving information from a JSON object in Angular using a specific key

After receiving JSON data from the server, I currently have a variable public checkId: any = 54 How can I extract the data corresponding to ID = 54 from the provided JSON below? I am specifically looking to extract the values associated with KEY 54 " ...

Component remains populated even after values have been reset

My child component is structured as shown below, ChildComponent.html <div> <button type="button" data-toggle="dropdown" aria-haspopup="true" (click)="toggleDropdown()"> {{ selectedItemName }} <span></span> </but ...

What is the best way to access the vue3datepicker object in order to manually close the date picker popup user interface?

Enhancement After yoduh's feedback, I made adjustments to the code below. However, vue3datepicker is still undefined. Code has been updated according to yodubs suggestion. I consulted the official vue3datepicker documentation to customize my own Act ...

Custom type checker that validates whether all properties of a generic object are not null or undefined

In an attempt to create a user-defined type guard function for a specific use-case, I am faced with a challenge: There are over 100 TypeScript functions, each requiring an options object. These functions utilize only certain properties from the object wh ...

Injecting singletons in a circular manner with Inversify

Is it possible to use two singletons and enable them to call each other in the following manner? import 'reflect-metadata'; import { Container, inject, injectable } from 'inversify'; let container = new Container(); @injectable() cla ...

Make sure to refresh the state of the store whenever there is a change detected in the input

I am experiencing an input delay problem when trying to update the state of a zustand variable in the onChange event. const BuildOrder = (props: { setOpen: Function }) => { const { almacenes, isLoadingAlmacenes } = useGetAlmacenes(); const { article ...

Error: Component with nested FormGroup does not have a valid value accessor for form control in Angular

In my setup, the parent component is utilizing a FormGroup and I am expecting the child components to notify any changes in value back to the parent. To achieve this, I am trying to implement NG_VALUE_ACCESSOR in the child component so that it can act like ...

Pixijs is unable to load spritesheets correctly

I am currently facing an issue while trying to load a spritesheet in PixiJS following the instructions provided on Below is the code snippet I am using: PIXI.Loader.shared.add('sheet', require('../assets/spritesheet.json')).load(sprite ...

Learn how to resubscribe and reconnect to a WebSocket using TypeScript

In my Ionic3 app, there is a specific view where I connect to a websocket observable/observer service upon entering the view: subscribtion: Subscription; ionViewDidEnter() { this.subscribtion = this.socket.message.subscribe(msg => { let confi ...

Exploring Angular Component Communication: Deciphering between @Input, @Output, and SharedService. How to Choose?

https://i.stack.imgur.com/9b3zf.pngScenario: When a node on the tree is clicked, the data contained in that node is displayed on the right. In my situation, the node represents a folder and the data consists of the devices within that folder. The node com ...

Is it possible to eliminate additional properties from an object using "as" in Typescript?

I am looking for a way to send an object through JSON that implements an interface, but also contains additional properties that I do not want to include. How can I filter out everything except the interface properties so that only a pure object is sent? ...

Oops! The react-social-media-embed encountered a TypeError because it tried to extend a value that is either undefined, not a

I recently attempted to incorporate the "react-social-media-embed" package into my Next.js project using TypeScript. Here's what I did: npm i react-social-media-embed Here is a snippet from my page.tsx: import { InstagramEmbed } from 'react-soc ...

Guide on sending files and data simultaneously from Angular to .NET Core

I'm currently working on an Angular 9 application and I am trying to incorporate a file upload feature. The user needs to input title, description, and upload only one file in .zip format. Upon clicking Submit, I intend to send the form data along wit ...

Utilizing TypeScript Generics for Creating Arrays of Objects with Inherited Type Definitions

I'm exploring the concept of type inheritance for an array of objects, where one object's value types should inherit from another. While I'm unsure if this is achievable, it's definitely worth a try. Currently, I believe my best approac ...

The 'validate' property within the 'MappingService' class cannot be assigned to the 'validate' property in the base class 'IMappingService' in typescript version 2.8.0

Currently, I am utilizing the AngularJS framework (version 1.5.8) in tandem with the latest TypeScript files (2.8.0). However, upon updating to the newest version of TypeScript, the code below is failing to compile. The IMappingService interface: export ...

The Datatable is displaying the message "The table is currently empty" despite the fact that the rows have been loaded through Angular

My experience with displaying a data table in Angular was frustrating. Even though all the records were present in the table, it kept showing "no data available." Additionally, the search function refused to work as intended. Whenever I tried searching for ...