Can you explain the purpose of the `never[]` parameter type as defined in the TypeScript Handbook?

Exploring the topic of Inferring Within Conditional Types, an illustrative example is provided:

type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
  ? Return
  : never;

type Num = GetReturnType<() => number>;
type Str = GetReturnType<(x: string) => string>;
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;

But the choice of never[] in this context raises questions.

Answer №1

The purpose behind

type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
  ? Return
  : never;

is to extract the return type of any function without discriminating based on parameter types. Any function signature passed in as Type should be assignable to

(...args: never[]) => infer Return
. This means that
(...args: never[]) => infer Return
should encompass all function signatures as a top type for functions.
For further insight, refer to Alternative for "any function" ((...args: any[]) => any) without using any.


Considering that the parameters of Type are disregarded and no actual function call of type Type is made, there are various ways to define a function top type in TypeScript for this purpose. Here are different options listed in descending order of preference:

  • (...args: never) => infer Return
  • (...args: any) => infer Return
  • (...args: any[]) => infer Return
  • (...args: never[]) => infer Return

Function types exhibit contravariance in their parameter types, meaning a function type should align with fewer parameter types to match a wider range of function types. Consequently, for a top type that encompasses all function types, a bottom type for the parameters (i.e., an intersection of all parameter types) is required.

The "never" type serves as TypeScript's bottom type, making

(...args: never) => infer Return
the ideal function top type for type safety.

Alternatively, you can utilize any type for this purpose, such as

(...args: any) => infer Return
. The intentional unsafety of the any type makes it suitable for scenarios where type is inconsequential and errors need to be avoided.

Another option is to use

(...args: any[]) => infer Return
, as any[] can accommodate any array type.


Lastly, there's

(...args: never[]) => infer Return
. A type of never[] signifies "an unindexable array," covering nearly all array types but not the precise intersection of all array types. Although it aligns with most functions, it should behave distinctively when called. While TypeScript treats (...args: never) => ? and (...args: never[]) => ? as identical, there are intricacies and bugs related to these types, as indicated in microsoft/TypeScript#48840.

However, given that the function is not invoked in this scenario, the distinction between never[] and never is mainly theoretical. For the purpose of GetReturnType, never[] is equally suitable as never.

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 difficulty in fetching data from a service with ng-select

Currently, I am utilizing ng-select for a form that allows users to search for activities to add. The ng-select component triggers a function whenever something is typed into the field. This function then calls a service that fetches an array of activities ...

Interpolating strings in a graphQL query

Exploring the world of Gatsby and its graphQL query system for asset retrieval is a fascinating journey. I have successfully implemented a component called Image that fetches and displays images. However, I am facing a challenge in customizing the name of ...

Tips for sorting server components using a URL search parameter [Next.js, Prisma]

My goal is straightforward: I want to be able to filter my Prisma database based on parameters passed in the URL when I click on a CategoryBox. After clicking on a CategoryBox, my URL does change to something like http://localhost:3000/?category=XYZ, but ...

When trying to access an array within a nested reactive form group, a linting error was encountered

I'm currently working on a method to delete rows from a dynamic form, but I am struggling to target the array. The structure of my form group is as follows: this.piForm = this.fb.group({ milestoneSaveModel: this.fb.group({ milestonesToCr ...

I am in need of assistance with incorporating a particular hibernate Inheritance mapping into my project

I am dealing with a situation where I have two classes, parent and child, with a self-referential relationship on the child side. The database is set up with separate tables for both parent and child, sharing the same "id", and using the column "holder" as ...

When evaluating code with eval, properties of undefined cannot be set, but the process works seamlessly without

Currently, I am attempting to utilize the eval() function to dynamically update a variable that must be accessed by path in the format myArray[0][0[1][0].... Strangely enough, when I try this approach, I encounter the following error: Uncaught TypeError: ...

Setting style based on the condition of the router URL

I am currently facing an issue with a global script in Angular 10 that is supposed to evaluate the current path and apply a style to the navigation bar conditionally. However, it seems to fail at times when using router links. I am wondering if there is a ...

"Embracing the power of multiple inheritance with Types

I am struggling with the concept of multiple inheritance in TypeScript. It doesn't make sense to overload a hierarchy with too much functionality. I have a base class and several branches in the hierarchy. However, I need to utilize mixins to isolate ...

How can I access a file uploaded using dxFileUploader?

I am facing an issue with retrieving a file from dxFileUploader (DevExpress) and not being able to read it in the code behind. The file is only appearing as an object. Here is My FileUploader : { location: "before", ...

An issue has been detected in the @angular/material/autocomplete/typings/autocomplete-origin.d.ts file: The type 'ElementRef' is not declared as a generic type

Recently, I downloaded an Angular template that utilizes the Angular Material library. While trying to run this template on my local machine, I successfully executed the npm install command. However, when attempting to run ng serve, I encountered several w ...

Access functions and attributes in separate namespaces using a callback function

Incorporating the chartjs-plugin-annotation, I am faced with the need to trigger an event once a user clicks on an annotation to display a tooltip text. The plugin offers an event handler for the click event that allows me to retrieve the clicked element: ...

Using mat-form-field with the outline appearance seems to be causing some issues

When I change the body direction to RTL, the mat-form-field with appearance"outline" seems to have some issues. If you go to the https://material.angular.io site and navigate to the Form field examples, under the Form field appearance variants section, yo ...

Managing the rxjs from an Array of observables when the array has no elements

Looking for a more elegant solution to handle the case where an array of observables is empty in the following TypeScript function. I want the observable to complete when subscribe() is called without the need for an initial check. I've already imple ...

Establish a reactive form upon data completion (asynchronously) in Angular version 5

I've been encountering an issue with updating form values post fetching data from an API. I attempted to utilize the *ngIf technique, but unfortunately, the form remains invisible even though it is properly set. Although I cannot provide the entire p ...

Angular2 form builder generating dynamic forms based on results of asynchronous calls

When creating my form, I encountered a challenge with passing the results of an asynchronous call to the form builder. This is what I have attempted: export class PerformInspectionPage implements OnInit { checklists: any; inspectionform: FormGroup; n ...

Error in Typescript: Uncaught TypeError: Unable to access the `value` property of null at HTMLButtonElement.document.getElementById.addEventListener.event

Hello, I'm facing an issue with a simple Typescript calculator and I can't seem to figure out what's causing the problem. I'm puzzled as to why I'm receiving a null value because the element IDs appear to be correct. HTML : X: ...

How to Retrieve Input Field Value Using Cypress Custom Command

Is there a way to retrieve the value of an input[text] element within a custom command? Cypress.Commands.add('extendValue', { prevSubject: 'element' }, (subject: JQuery<HTMLElement>, extension: string): any => { const r ...

Service error: The function of "method" is not valid

In one of my Angular 2 applications, I have a class that contains numerous methods for managing authentication. One particular method is responsible for handling errors thrown by the angular/http module. For example, if a response returns a status code o ...

Determining a value that increases to yield a fresh sum

I'm currently developing a character generator that determines your score based on the experience points you allocate to it. The scoring system is such that 1 XP gives you a score of 1, 3 XP gives you a score of 2, 6 XP gives you a score of 3, 10 XP g ...

An example in Typescript for setting an initial/default value for a data type

Can you create a Type with a default value included? For example: type Animal = { kind : "animal" Legs : number, CanFly: boolean } const monkey: Animal = { Legs: 4, CanFly: false}; //In this line, clients must initialize the same value `kin ...