Not all generic types specified with an extends clause are appropriately narrowed down as expected

Consider the following scenario:

type MyType = 'val1' | 'val2' | 'val3';

const variable = 'val1' as MyType;

const val2 = 'val2';
const val3 = 'val3';

declare function test<U extends MyType>(...args: U[]): void;

test(val2, val3); // U successfully resolves to "val3" | "val2"

declare function test2<T, U extends T>(value: T | undefined, ...values: U[]): void;

test2(variable, val2, val3); // U gets widened to "val1" | "val2" | "val3"

In both functions test and test2, U extends MyType.

It was expected that test2 would also resolve U to

"val3" | "val2"
, similar to how it did in test, but this is not the case.

What could be the reason for this discrepancy?

Visit TypeScript playground for more

Answer №1

It seems like the type system in Typescript sometimes takes shortcuts when checking types. Typescript may cut corners if it determines that the resulting type won't be used elsewhere in the system. For example, the type "val1" | "val2" | "val3" might be considered sufficient for an arguments list by Typescript. However, if we were to change the return type of test2 from void to U, where U is expected to be returned and used elsewhere in the codebase, the compiler would need to spend more time determining the exact type of U.

type MyType = 'val1' | 'val2' | 'val3';

const variable = 'val1' as MyType;

const val2 = 'val2';
const val3 = 'val3';

declare function test2<T, U extends T>(value: T | undefined, ...values: U[]): void;

test2(variable, val2, val3); // U will be widened to "val1" | "val2" | "val3";

declare function test3<T, U extends T>(value: T | undefined, ...values: U[]): U;

test3(variable, val2, val3); // U will successfully resolve to "val3" | "val2";

Try it out in the 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

Encountering an error in Angular2 and TypeScript: TS2322 error message stating that the type 'Response' cannot be assigned to type 'UserStatus'

Currently, I am facing some challenges while working with Angular2 and TypeScript. Transitioning from AngularJS to Angular2 has proven to be a bit tricky for me. To better understand this new framework, I decided to create an experimental app with the foll ...

Unlocking Not Exported Type Definitions in TypeScript

Take a look at this TypeScript code snippet: lib.ts interface Person { name: string; age: number; } export default class PersonFactory { getPerson(): Person { return { name: "Alice", age: 30, } } } ...

Tips on how to increase and update the index value by 2 within an ngFor loop while maintaining a fixed format

I have a specific template layout that displays only two items in each row as shown below. I want to use the ngFor directive to iterate through them: <div class="row" *ngFor="let item of cityCodes; let i = index"> <div class="col-6" (click)= ...

Create a TypeScript view component that encapsulates an HTMLElement for seamless integration with TweenMax

Looking to develop my own basic view component class that encompasses an HTMLElement or JQuery element, I want to be able to do something similar to this: var newComponent:CustomComponent = new CustomComponent($('#someDiv')); TweenMax.to(newCom ...

What is preventing absolute paths from functioning properly in TurboRepo?

After setting up a fresh project on the most recent version of TurboRepo, I ventured into the 'apps' directory and established a new Vite project using the 'react-swc-ts' template. Making tweaks to the 'tsconfig.json' file wit ...

Implementing Expand/Collapse functionality for multiple TableRow components in Material-UI

Using a Material UI table and attempting to expand the `TableRow` inside a collapse table, but encountering an issue. Currently, all collapses are connected to one state for "open," causing all lists to open if one is clicked. What is the optimal approach ...

Encountered an error trying to access '0' property of an undefined object when iterating through data in angular framework

My API is returning data in the format shown below: "fileName": "data.txt", "onlyInFile1": [ { "_id": "60618e87c2077428e4fedde5", "TERMINAL_ID": "Y6152114", "EXTERNAL_STAN": & ...

Issue stemming from reactivity causing difficulties with Vuex data mutation within actions

I have a Vuex store action that needs to interact with the API using new data for updating purposes. My goal is to create a separate object that mirrors an existing value in the store, allowing me to manipulate it without affecting reactivity. However, w ...

What can be done to prevent the angular material select from overflowing the screen?

I have integrated an Angular Material Select component into my application, which can be found here: https://material.angular.io/components/select/overview. The issue I am facing is that when the select element is positioned near the bottom of the screen a ...

Neglecting the error message for type assignment in the Typescript compiler

Presented here is a scenario I am facing: const customer = new Customer(); let customerViewModel = new CustomerLayoutViewModel(); customerViewModel = customer; Despite both Customer and CustomerLayoutViewModel being identical at the moment, there is no ...

Can I retrieve the return type of useFetch in Nuxt3?

I am running into an issue while trying to specify the APIBody type in the following manner: Property 'test' does not exist on type 'NonNullable<PickFrom<_ResT, KeysOf>>'. It seems like there is no straightforward way to def ...

Developing an Angular 2 Cordova plugin

Currently, I am in the process of developing a Cordova plugin for Ionic 2. The plugin is supposed to retrieve data from an Android device and display it either on the console or as an alert. However, I am facing difficulty in displaying this data on the HT ...

TypeScript generic type and potential absence of a value

Recently, I've been delving into Facebook's immutable library and exploring their TypeScript bindings. Consider this snippet of code: const list: User[] = ...; list.map(user => ...) The lambda parameter user correctly has the type of User. ...

Is it feasible to develop a TypeScript module in npm that serves as a dual-purpose tool, functioning as both a command line utility

My goal is to develop an npm TypeScript module that serves dual purposes - acting as a command line utility and exporting methods for use in other modules. The issue arises when the module intended for use as a command line utility requires a node shebang ...

No information is being emitted by the subject

In my application, I have a feature where users input data that needs to be validated in a form. Once the validation is successful, a button is enabled allowing the user to submit their order. However, I'm facing an issue with this specific component ...

The library "vue-property-decorator" (v10.X) is causing issues with resolving in Webpack despite being successfully installed

Encountered an error message Module not found: Error: Can't resolve './decorators/Emit' while attempting to import functionality from the library vue-property-decorator. The package is installed and accessible, ruling out a simple installati ...

What is the process for consumers to provide constructor parameters in Angular 2?

Is it possible to modify the field of a component instance? Let's consider an example in test.component.ts: @Component({ selector: 'test', }) export class TestComponent { @Input() temp; temp2; constructor(arg) { ...

Show the subscription response data in Angular

When utilizing the code snippets below from two different components, I am able to receive a valid response value from the subscriber. dataService.ts fetchFormData(){ return this.http.get('http://localhost:48116/RecuruitmentService.asmx/addRoleTest ...

Tips for inserting an object into an array

Here's the data I received: { 0:{modifierId: 4, modifierName: 'Garlic', modifierPrice: 60 } 1:{modifierId: 1, modifierName: 'Tartar ', modifierPrice: 60} 2:{modifierId: 3, modifierName: 'Herb ', modifierPrice: 60} item ...

Automatically closing the AppDateTimePicker modal in Vuexy theme after selecting a date

I am currently developing a Vue.js application using the Vuexy theme. One issue I have encountered is with a datetimepicker within a modal. The problem arises when I try to select a date on the datetimepicker component - it closes the modal instead of stay ...