Navigating Unpacked Varied Tuple Types

Here is the code snippet to consider:

interface Wrap<Value> {
  pick(): Value
}

class WrapConstant<Value> implements Wrap<Value> {
  constructor(public readonly a: Value) { }
  pick(): Value { return this.a }
}

type Unwrap<Wrapped> = { [P in keyof Wrapped]: Wrapped[P] extends Wrap<infer Value> ? Value : never }

class WrapTuple<Tuple extends Wrap<unknown>[], Value = Unwrap<Tuple>> implements Wrap<Value> {
  readonly ts: Tuple
  constructor(...t: Tuple) { this.ts = t }

  pick(): Value { return this.ts.map(a => a.pick()) }                // fails to type check
}

type T1 = Unwrap<[WrapConstant<number>, WrapConstant<string>]>       // [number, string]

new WrapTuple(new WrapConstant(1), new WrapConstant("hello")).pick() // [1, "hello"]

In essence, I am trying to unwrap a tuple following a specific structure (tuple of Wrap<Values>). However, there seems to be a type check error with the pick() function in WrapTuple. Here are some questions regarding this issue:

  1. Could the reason for this error be because Unwrap<Tuple> might not have a consistent shape due to conditional type inference?
  2. Is there a way to resolve this without resorting to casting it as as unknown as Value?

Update: Linda pointed out that mapping a tuple does not yield another tuple. To address this, I attempted to implement my own version of map mentioned in this here:

interface Array<T> {
  map<U>(callbackfn: (value: T, index: number, array: T[]) => U, 
         thisArg?: any): { [K in keyof this]: U }
}

However, even with this implementation, I still need to assert the map method's return value as Value:

pick(): Value { return this.ts.map(a => a.pick()) as Value }

Answer №1

UPDATED

Check out this solution:

interface Wrap<Value> {
    pick(): Value
}

class WrapConstant<Value> implements Wrap<Value> {
    constructor(public readonly a: Value) { }
    pick(): Value { return this.a }
}

type Unwrap<Wrapped> = { [P in keyof Wrapped]: Wrapped[P] extends Wrap<infer Value> ? Value : never }

class WrapTuple<Tuple extends ReadonlyArray<Wrap<unknown>>> implements Wrap<unknown> {
    readonly ts: Tuple
    constructor(...ts: [...Tuple]) {
        this.ts = ts
    }

    pick(): Unwrap<[...Tuple]> // <-- additional overload
    pick() {
        return this.ts.map(a => a.pick())
    }
}


const foo = new WrapTuple(new WrapConstant(1), new WrapConstant("hello")).pick() // [number, string]

Playground

The method overloading seems to be working as intended

Here you can discover more strategies with tuples. This is my personal blog

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 is the reason behind create-next-app generating .tsx files instead of .js files?

Whenever I include with-tailwindcss at the end of the command line, it appears to cause an issue. Is there any solution for this? npx create-next-app -e with-tailwindcss project_name ...

Utilize a unique method of accessing objects through a combination of an object along with two specific

I am looking to create a function that combines an object, a path in a variable, and another path, similar to what is described in this StackOverflow post, but with 3 different components. Here is a simple example to illustrate my goal: I want the combine ...

Error 2322: Troubleshooting Typescript arrow functions overloads issues

Everything seems to be working well with the code below, except for an error that occurs with the resolve constant. const resolve: Resolve Type '(param: "case 1" | "case 2" | "case 3") => boolean | "string" | ...

Integrating concealed elements into jspdf

I am currently working on incorporating a hidden div into my jspdf file. Utilizing html2canvas for this purpose, I find it necessary to briefly make the div visible, add it to the pdf, and then hide it again. This method is not ideal as the content moment ...

Creating Dynamic Graphs using Angular and Chart.js with Array Values

I have implemented ChartJS-2 to visualize a graph displaying an array of user activities, but it appears distorted: import { Component, OnInit, Input } from '@angular/core'; import { ChartOptions, ChartType, ChartDataSets } from 'chart.js ...

Is your React Native list elements feeling a little too close for comfort?

I'm facing an issue where the items in my list are not properly spaced out and I'm unable to figure out why. I have 3 elements for each letter that should be separated from each other. I suspect that the issue might be related to the fact that th ...

The sequence of initializing test hooks in inconsistent playwright tests

My testing framework setup looks something like this: test.describe("...", () => { let p: Page; test.beforeEach(async({browser}) => { p = await (await browser.newContext()).newPage(); } test(...); test(...); test.aft ...

What is the best way to implement a custom layout with nuxt-property-decorator?

Summary of Different Header Components in Nuxt In order to set a different header component for a specific page in Nuxt, you can create separate layout files. layout ├ default.vue // <- common header └ custom.vue // <- special header for s ...

The AutoComplete feature of MaterialUI Component fails to function properly even when there is available data

I am facing an issue with my component as it is not displaying the autosuggestions correctly. Despite having data available and passing it to the component through the suggestions prop while utilizing the Material UI AutoComplete component feature here, I ...

In functions, Typescript does not have the ability to automatically infer undefined or null checking

I'm facing an issue related to Typescript type checking while working with functions. Let's assume I have a Type called IBaseField and a variable of Type Array<IBaseField>. When trying to assign a value to this variable, I consistently chec ...

Examining Angular unit test coverage on Window.Location.Href

Currently, I am utilizing Angular 7 and endeavoring to create some unit tests for this basic component. export class DialogComponent implements OnInit { appError: any; httpErrorResponse: HttpErrorResponse; constructor( public dialogRef: MatDi ...

Is it possible to continuously re-render a React Functional Component with Axios and useState/useEffect?

Seeking assistance with creating a React Functional Component using Typescript to fetch data from an API and pass it to another component. However, encountering the error message "Error: Too many re-renders. React limits the number of renders to prevent an ...

Determine Data Types from Text

Developing a game involving client/server communication, where different communication "Channels" with unique names and structures are utilized. To simplify the process of handling these channels and their expected parameters, I created an interface as fol ...

What is the optimal method for navigating through a complex nested object in Angular?

Looking to navigate through a nested object structure called purchase. Within this structure, there is a sub-array named purchaseProducts which contains another sub-array called products along with additional data. What methods do you suggest for efficien ...

How about this: "Imagine having a Record<string, string> in which all keys are strings except for one key that is

I need to define a TypeScript type in the following format: type Route = Record<string, string> & { buildUrl: (params: Record<string, string>) => string } An example object of this type would be: const route: Route = { base: ' ...

I am looking for a way to convert the date format from "yyyy-MM-dd" to "dd-MM-yyyy" in NestJs

I need help with changing the date format from "yyyy-MM-dd" to "dd-MM-yyyy". Currently, my entity code looks like this: @IsOptional() @ApiProperty({ example: '1999-12-12', nullable: true }) @Column({ type: 'date', nullable: true } ...

Angular form group allows you to iterate through an array of forms seamlessly

When pulling data from the server, I need to display it in a series of spans, as illustrated below: https://i.sstatic.net/c2wmM.png Each row represents an item in the list, and keep in mind that this list is generated using *ngFor like so: this.myForm = ...

What is the reasoning behind TypeScript allowing the reading of an undefined variable within a closure?

While exploring, I came across this detail that seems undocumented. Here's some legitimate TypeScript code that results in undefined being output: let x: number; const f= () => { const y= x; console.log(y); } f(); Playground Within the fu ...

Error in Angular 5: Google Maps not defined

Having trouble implementing Google Maps on my Angular 5 app. Upon loading the view, I am encountering this error in the JavaScript console: LoginComponent_Host.ngfactory.js? [sm]:1 ERROR ReferenceError: google is not defined at LoginComponent.ngAfterVie ...

AWS Lambda is consistently showing a 10-second delay before the function finally ends once the code

https://i.sstatic.net/kcB03.png In a TypeScript Lambda API I developed, there is a specific point where the callback complete logs occur. Following those logs, the lambda takes approximately 10 seconds to respond as shown by the timestamps. export const h ...