What causes TypeScript generics to infer varying types when an array member is enveloped?

I'm having trouble finding an answer to this potentially duplicate question, so please redirect me if it has already been addressed.

My experience with generics in TypeScript has shown me that the inferred types can vary based on whether a generic is wrapped when used as an array member. Here are two examples:

// Setting up
type Wrapped<I> = { _i: I };

// Example where it doesn't work
function foo1<TInner extends unknown>(bar: Wrapped<TInner>[]) {
  return bar;
}
const a = foo1([{ _i: 5 }, { _i: "six" }]); // TInner = number, compiler error for second array member despite inference

// Example where it works
function foo2<TInner extends Wrapped<unknown>>(bar: TInner[]) {
  return bar;
}
const b = foo2([{ _i: 5 }, { _i: "six" }]); // TInner = Wrapped<number> | Wrapped<string>

Why does this happen? Is there missing information in the documentation? Can someone guide me to a clear explanation of how TypeScript infers generics?

Answer №1

Examine the code structure closely.

// A slightly modified example

type Wrapped<I> = { _i: I };

function foo<T extends unknown>(baz: Wrapped<T>[]) {}

foo1([ { _i: 5 }, { _i: "six" } ]);

function bar<T extends Wrapped<unknown>>(baz: T[]) {}

foo2([ { _i: 5 }, { _i: "six" } ]);

The generic parameter in foo, defined as T extends unknown, allows for T to take on any value, indicated by unknown, but it must be a singular type.

The function's parameter is Wrapped<T>[]; this means that foo accepts an array of Wrapped<T>, requiring every item to have the same type. For example, it can accept

[ { _i: 1 }, { _i: 2 }, { _i: 3 } ]
or
[ { _i: 'a' }, { _i: 'b' }, { _i: 'c' } ]
, but not a mixed type array like
[ { _i: 'a' }, { _i: 2 }, { _i: Symbol(NaN) } ]
.

In contrast, bar is defined as

<T extends Wrapped<unknown>>
, allowing T to simply be an object of type Wrapped, regardless of its specific type parameter.

To summarize, foo expects a uniform array of one type, while bar accepts an array of various Wrapped objects.

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

Is the Ajax response value consistently 1?

I am facing an issue where a JavaScript in an HTML page is sending two variables to a PHP script, which then echoes one of the variables at the end. However, the response value always remains 1. Despite trying methods like alerting, console.log, and puttin ...

The Google Closure Compiler Service is providing faulty code

I've been using Closure Compiler through to minify and obfuscate my JavaScript code, but I seem to be encountering an issue. To troubleshoot, I created a test page with a script. Here's the HTML5 code snippet: <!DOCTYPE html> <html> ...

Trigger a JavaScript function using PHP and retrieve the output

My goal is to execute a javascript function from a PHP script by passing a variable to the javascript function and then displaying only the response in the PHP script. I want to ensure that when a client views the source code of my php file, they can only ...

Struggling to properly send props to the child component in Vue 3

Is there a way to pass data from the request through axios in the root component to the child using Vue? Currently, only the "title" field is displayed correctly, but I also need to output the "body". Note: This is my first time working with Vue and I&apo ...

What is the correct way to specify the type in my functional component?

I was trying to define the type in my component in a different way, I know it can be done using classes but is there a way to achieve this with functional components without exporting the interface? Despite my extensive research, I couldn't find any r ...

A curated collection saved in LocalStorage using React JS

I have implemented a LocalStorage feature to create a favorite list, but it only adds one item each time the page is reloaded. The items are retrieved from a JSON file. For a demonstration of how my code functions, check out this link: const [ storageIte ...

Enhance dynamically generated HTML using jQuery Mobile

Using jQuery Mobile version 1.2.0 I am dynamically generating HTML using JavaScript ($(selector).html(content)), adding it to the DOM, and then displaying it ($.mobile.changePage()). After that, I make an AJAX call, retrieve some data, and re-generate th ...

Is there a more effective alternative to using the ternary condition operator for extended periods of time?

Do you know of a more efficient solution to handle a situation like this? <tr [style.background]="level == 'ALARM' ? 'violet' : level == 'ERROR' ? 'orange' : level == 'WARNING' ? 'yellow' ...

The property cannot be set because it is undefined in nodejs

var list = [ { title : '', author : '', content : '', } ] router.get('/japan',function(req,res){ var sql = 'select * from japan'; conn.query(sql,function(err,rows,fields){ for(var i = 0 ; ...

Above the search box in jQuery Datatable's search box, there is search text displayed

My datatable looks like this: var exTable1 = $("#exTable").DataTable({ "language": { "search": "Filter", "searchPlaceholder": "search", "loadingRecords": "", }, data: datasrc "dom": '<"top"lf>rt<"botto ...

"Customize your map pins on Google Maps by updating the marker location through a

I am trying to update the position of a map marker based on a dropdown selection. Upon changing the dropdown option, I retrieve the latitude and longitude values and want to set these coordinates for my current marker. Here is the code snippet: $("#locati ...

Provide users with the option to select a specific destination for saving their file

In the midst of my spring MVC project, I find myself in need of implementing a file path chooser for users. The goal is to allow users to select a specific location where they can save their files, such as C:\testlocation\sublocation... Despite r ...

Transforming an Ext.data.TreeStore data structure into a JSON format

How can I convert an Ext.data.TreeStore to a string for saving to Local Storage? I tried using Ext.encode() but it's giving me a circular structure error. Has anyone encountered this issue and found a workaround? ...

Utilizing React hooks to capture the checkbox value upon change and transfer it to the submitForm function

I've got a functioning hook that monitors the onChange event of input fields, then spreads them into a variable and sends them to a Lambda function for sending an email with SendGrid. Everything is working fine. However, when I add an input type of c ...

Creating responsive arrow heads using D3: A step-by-step guide

Currently, I am working on creating a thermometer-style bar chart using D3.js version 3. While I have successfully created a basic responsive rectangle with two filled colors, I am facing difficulties in figuring out how to add arrow heads to the design. B ...

Checking that an object's keys are all present in an array in TypeScript should be a top priority

I am working with a const object that is used to simulate enums. My goal is to extract the keys from this object and store them in an array. I want TypeScript to generate an error if any of these keys are missing from the array. // Enum definition. export ...

Error: Unrecognized error encountered while using Angularjs/Ionic: Property 'then' cannot be read as it is undefined

codes: js: angular.module('starter.services', ['ngResource']) .factory('GetMainMenu',['$http','$q','$cacheFactory',function($http,$q,$cacheFactory) { var methodStr = 'JSONP' ...

Code snippet: Retrieve the previous and upcoming events based on the current date from an array (JavaScript/Angular)

Is there anyone who can assist me with an algorithm? I have a list of events and need to retrieve the next event and previous events based on the current date. For example: I fetch all events from an SQL database like so: events = [ {eventId:1, event ...

Enhancing the appearance of a JSX component in React

I have a segment of code within my project that calculates a specific percentage and displays it on the dashboard. <text className="netProfit-circle-text" x="50%" y="50%" dy=".2em" textAnchor="middl ...

Dnd-kit: item loses its place in line when dragged over Droppable area

I've encountered an issue while using @dnd-kit. The sorting function works smoothly (e.g. when I drag the 1st element, it sorts correctly), but once I reach a droppable element (green Thrash), the sorting breaks and the 1st element snaps back. You ca ...