typescript function intersection types

Encountering challenges with TypeScript, I came across the following simple example:

type g = 1 & 2 // never
type h = ((x: 1) => 0) & ((x: 2) => 0) // why h not never
type i = ((x: 1 & 2) => 0)// why x not never

The puzzling part is why type h isn't evaluated as never, and why parameter x in type i is not considered never.

type e = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never; //  why e is 2 not never or 1?

Furthermore, it's unclear why the type e resolves to 2 instead of never?

Answer №1

Note: when working with non-primitive types, it is customary to use UpperCamelCase for better differentiation from primitive types and variable/property names. This convention will be followed in the explanations that follow.

This question consists of multiple components, so the answer will also have several parts to address each aspect.


Let's start by addressing the simpler ones:

type G = 1 & 2 // results in never

The recent implementation in TypeScript starting from version 3.6 now reduces empty intersections like `1 & 2` to `never`. Previously, `1 & 2` was essentially behaving similarly to `never`, as there was no value that could satisfy this intersection. Conceptually, there is no distinction between `1 & 2` and `never`, although minor differences may arise due to compiler implementation specifics.


Moving on to another example:

type I = ((x: 1 & 2) => 0) // why x not never

In this case, even though `x` indeed evaluates to `never`, the reduction happens only when it is actually utilized:

type IParam = Parameters<I>[0]; // results in never

This deferred behavior was introduced in TypeScript version 3.9 through a specific update detailed in microsoft/TypeScript#36696. Prior to this update, `x` would have been instantly reduced to `never` similar to what happened in the previous scenario.


Now let's delve into more complex scenarios:

type H = ((x: 1) => 0) & ((x: 2) => 0) // why H not never

There are various reasons why `H` does not result in `never`:

  • From a TypeScript perspective, an intersection of function types behaves similar to an overloaded function with multiple call signatures:

    ...
  • Furthermore, according to the rules of contravariance with function parameter types, the system should return the union of parameter types for an intersection of functions. Hence, `1 | 2` is not equivalent to `never` within this context.

  • Even if hypothetically `H` were entirely uninhabited, TypeScript currently limits the reduction of intersections to `never` in specific cases, which excludes intersections of functions based on existing implementations in the compiler source code.


Lastly, we'll consider one final example:

type E = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never;
//  why E is 2 not never or 1?

In this instance, due to TypeScript's current design limitations regarding type inference with overloaded function types, the compiler selects just one call signature when inferring types, ignoring all other possibilities. Thus, in `E`, the compiler ends up inferring `L` as `2` instead of potentially considering `1 | 2`. This behavior is acknowledged as a limitation, as highlighted in relevant Github discussions such as microsoft/TypeScript#27027.


Access the Playground link here

Answer №2

in the event

let h = ((x: 1) => 0) & ((x: 2) => 0)

if you designate 1 as the type for x, this is known as a literal type. A literal type is the smallest set of values next to never. The distinction between never and literal type 1 is that never is an empty set, while 1 is a set with exactly one value in it. Therefore, never !== 1

over here

let i = (x: 1 & 2) => 0; 

the type of parameter x is 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

typescript what type of functionality do dynamic class methods provide

I'm currently working on building a class that creates dynamic methods during the constructor stage. While everything is functioning properly, I've encountered an issue with VS Code's auto suggestion not recognizing these dynamic methods. Ho ...

Understanding a compound data type in TypeScript

Hey there, I'm new to TypeScript and I'm facing a challenge in defining the type for an object that might have the following structure at runtime: { "animals" : [ { name: "kittie", color: "blue" }, { name: ...

Combining results from multiple subscriptions in RxJS leads to a TypeScript compiler error

I am utilizing an Angular service that provides a filterObservable. To combine multiple calls, I am using Rx.Observable.zip(). Although it functions as expected, my TypeScript compiler is throwing an error for the method: error TS2346: Supplied paramete ...

Removing HTML Tags in Ionic - A How-To Guide

After utilizing Ionic 3 to retrieve data from a WordPress API, I am encountering an issue with displaying the content on the app UI. The problem arises from the presence of HTML tags within the content being printed along with the text. While seeking solut ...

Error: The property 'process' cannot be read because it is not defined

Seeking help with a code issue Any advice on best practices would be greatly appreciated. Thank you! An error has occurred: TypeError: Cannot read property 'process' of undefined myComponent.ts ProcessInfo: any | false; showSaveItems = ...

Is there a method available that functions akin to document.getelementbyid() in this specific scenario?

Currently, I am tackling a project that involves implementing a search function. My initial step is to ensure that all input is converted to lowercase in order to simplify SQL calls. However, I have encountered a challenge that is proving difficult for me ...

Issue with importing MomentJS globally in TypeScript

When it comes to defining global external modules in TypeScript, there is a useful option available. For instance, if you have jQuery library loaded externally, you can set up a global definition without having to include its duplicate in the TypeScript bu ...

Using object bracket notation in TypeScript to retrieve values from props with the help of string interpolation

I encountered an issue in my code while attempting to utilize a variable within my TSX component. This problem arises due to the dynamic props being passed into the component, which are always a string that matches one of four keys in the "characters" obje ...

Having trouble verifying the selection option in Angular 6

I've been trying to implement Select option validation in Angular 6, but neither Aria-required nor required seem to be effective. The requirement is for it to display a message or show a RED border similar to HTML forms. Here's the HTML snippet ...

Determining the best application of guards vs middlewares in NestJs

In my pursuit to develop a NestJs application, I aim to implement a middleware that validates the token in the request object and an authentication guard that verifies the user within the token payload. Separating these components allows for a more organi ...

React: Implement a feature to execute a function only after the user finishes typing

Currently, I am using react-select with an asynchronous create table and have integrated it into a Netsuite custom page. A issue I am facing is that I would like the getAsyncOptions function to only trigger when the user stops typing. The problem right now ...

Injecting dynamic templates in Angular 7

Let me simplify my issue: I am currently using NgxDatatable to display a CRUD table. I have a base component named CrudComponent, which manages all CRUD operations. This component was designed to be extended for all basic entities. The challenge I am en ...

Sending data with an Http POST request in Angular 2

I'm having difficulty with a POST request that I am trying to make: sendRequest() { var body = 'username=myusername&password=mypassword'; var headers = new Headers(); headers.append('Content-Type', 'applicat ...

Understanding the appropriate roles and attributes in HTML for a modal backdrop element in a TypeScript React project

Trying to create a Modal component using React and TypeScript with a feature that allows closing by clicking outside. This is being achieved by adding a backdrop element, a greyed out HTML div with an onClick event calling the onClose method. Encountering ...

Is there a way to access the element reference of a component directly within the template?

When I mouse over certain elements, I use the following code to set focus: <div #divTemplateVar (mouseover)="divTemplateVar.focus()"></div> However, this method does not work for components: <component #componentTemplateVar (mouseover)="c ...

Cache for JSON Schema in VS Code

After updating to TypeScript 1.5 (now out of beta), I am eager to utilize the json schema helpers in VS Code. Upon configuring tsconfig.json, I noticed that only commonjs and amd module options are available, while umd and system are missing based on this ...

Importing libraries in TypeScript and JavaScript are not done in the same manner

As I create my own library, I aim for it to be compatible with both javascript and typescript. tsconfig.json { "compilerOptions": { "target": "es2017", "module": "commonjs", &qu ...

Anticipate the middleware function to either invoke the next function or return a HTTP 400 status code

I am eager to delve into unit testing and am looking to test my Node API. I am utilizing Express with Typescript and Jest for testing. Prior to invoking the controller middleware, I apply the route input validation middleware to verify the validity of the ...

Angular 2 code test coverage

Looking to calculate the code coverage of my Angular 2 code. Wondering if there are any plugins available for VS Code or WebStorm that can assist with this. My unit testing is done using Jasmine and Karma. ...

If the user clicks outside of the navigation menu, the menu is intended to close automatically, but unfortunately it

I have a nav file and a contextnav file. I've added code to the nav file to close the navigation when clicking outside of it, but it's not working. How can I ensure that the open navigation closes when clicking outside of it? Both files are in ts ...