Why is the type considered a union when comparing any to void?

I was curious to see what would happen when a type was checked if it was void, and I found the result interesting. It seems that when the input is any, a union is returned. Can someone shed some light on why this occurs?

type test<T> = T extends void ? void extends T ? 1 : 0 : 0;

type v1 = test<any>; // 1 | 0
type v2 = test<unknown>; // 0
type v3 = test<undefined>; // 0
type v4 = test<null>; // 0
type v5 = test<never>; // never
type v6 = test<void>; // 1
type v7 = test<boolean>; // 0
type v8 = test<string>; // 0
type v9 = test<number>; // 0
type v10 = test<'void'>; // 0
type v11 = test<{}>; // 0

Playground

Answer №1

For a comprehensive explanation, refer to microsoft/TypeScript#40049. When any is examined using a conditional type, the outcome will encompass both the true and false branches as a union. Despite being unexpected, this behavior is intentional.

Key insight:

Although not extensively documented beyond the source code, within the checker's relevant segment:

// Return union of trueType and falseType for 'any' since it matches anything
if (checkType.flags & TypeFlags.Any) {

Thus, any is essentially treated like a wildcard that encompasses both scenarios.

Answer №2

My understanding is as follows:

void extends any ? 1 : 0 results in 1, indicating that void does indeed extend any. This seems to be a deliberate choice by the authors of Typescript, although the rationale behind it is not clear. In my experiments, all types were found to extend any (verified with

{}, () => 1, "v", 3, unknown
).

On the other hand, any extends void ? 1 : 0 evaluates to 1 | 0, which makes sense since it could be one of the two types in the conditional type.

Therefore,

 ==> test<any>
     === any extends void ? void extends any ? 1 : 0 : 0
     === any extends void ? 1 : 0
     === 1 | 0

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

Issue with Angular2 input not firing the change event

I am facing an issue where the (change) event is not triggered when updating an input field that is being updated from a query. Here is the HTML code for the input: <input type="text" [ngModel]="inputValue" id="itemText" (ngModelChange)="setNewItem($e ...

Exploring unit tests: Customizing an NGRX selector generated by entityAdapter.getSelectors()

Let's imagine a scenario where our application includes a books page. We are utilizing the following technologies: Angular, NGRX, jest. To provide some context, here are a few lines of code: The interfaces for the state of the books page: export int ...

An array that solely needs a single element to conform to a specific type

While I was pondering API design concepts, a thought crossed my mind. Is it feasible to define a type in this manner? type SpecialArray<Unique, Bland> = [...Bland[], Unique, ...Bland[]]; However, the error message "A rest element cannot follow anoth ...

Struggling to implement React.RefObject in TypeScript

I am currently in the process of converting this class module to Typescript, but I am having trouble defining the object reference correctly. To view the example, click here. My current definition for the reference holder is as follows: private wrapperRe ...

Obtaining a value from within an Angular 'then' block

I have a unique issue that I haven't been able to find a solution for on StackOverflow: Within an Angular 6 service, I am trying to call a function from another service using TypeScript. Here is the code snippet: Service1: myArray: Array<IMyInte ...

Unlock the power of asynchronous dependencies on a global scale with Inversify

I'm looking to resolve an asynchronous dependency at the top level without relying on top-level awaits. Currently, I've implemented a temporary solution by defining an asynchronous function getService() in the controller file. However, this appr ...

Tips for positioning the border properly within a scrollable table

My table has a sticky header with a fixed height, and in order to see more rows in the table, we have to scroll through them. The table design includes borders. The problem arises when there are more rows, as the border moves with the scroll. Initially, ...

Using type annotations and discriminated unions with string literals

Recently, I encountered an issue while trying to create objects that adhere to a specific type annotation (Cards). The challenge was with a property that needed to match a discriminated union of string literals (CardType). These string literals were identi ...

What could be causing the issue with dayjs dynamic importing in TypeScript?

Currently, I am developing a web screen within a .NET application and facing an issue with sending datetime preferences from the system to the web screen using CefSharp settings. AcceptLanguageList = CultureInfo.CurrentUICulture.Name In my TypeScript code ...

The object's null status remains uncertain even after being checked for null

Currently, I am working with Typescript 2.8 This is the code snippet that I have: class Wizard extends React.Componenet { private divElement: null | HTMLDivElement = null; componentDidUpdate(_: IWizardProps, prevState: IWizardState) { i ...

Issue encountered in Angular 4 due to XSS script in URL causing "Cannot match any routes" error

I've been working on a project in Angular 4 and encountered an issue while setting up routes for a feature module. The error message I'm receiving is Error: Cannot match any routes. Below is the code snippet of the routes I've defined: con ...

Encountering the error "Unable to access property message of null" while trying to retrieve the error status code from an HTTP response in Angular

I'm currently working on a project using Angular 8 where I am making an HTTP post request to a .NET Core Web API. If the username or password is incorrect, the API returns a status code of 400. Despite the Chrome console indicating that a 400 status h ...

Utilize the power of generics with Angular's service providers

Is it possible to make the membervar of class Parent generic instead of type any, while still retaining the ability to switch provider classes without having to update all components that rely on class Parent? For example, if class ChildB implements a diff ...

Next.js experiencing hydration error due to dynamic component

Having an issue with my RandomShape component, where it should display a random SVG shape each time the page is reloaded. However, I am encountering a hydration error on the client side. import React from "react"; import shapes, { getRandomShape ...

Managing the re-rendering in React

I am encountering a situation similar to the one found in the sandbox example. https://codesandbox.io/s/react-typescript-fs0em My goal is to have Table.tsx act as the base component, with the App component serving as a wrapper. The JSX is being returned ...

`Can you bind ngModel values to make select options searchable?`

Is there a way to connect ngModel values with select-searchable options in Ionic so that default values from localStorage are displayed? <ion-col col-6> <select-searchable okText="Select" cancelText="Cancel" cla ...

Refreshing functionality with a Dockerized Node-Typescript application for instant updates

Currently, I am in the process of dockerizing an API container and aiming for it to have the ability to hot reload whenever there is a code change. I have set up a volume to manage this, but unfortunately, nothing seems to happen when changes are made. Be ...

In a React Enzyme test, establish the clientHeight and scrollHeight values for ref.current

I need help testing a callback function triggered by clicking on an element rendered by my function component. The problem is that this element is only displayed when the clientHeight and scrollHeight of a ref are different. However, both values are showin ...

Retrieve a specific data point from a web API using Angular framework

Objective: How can I retrieve the specific value "test" in Angular? Issue: An error message is being displayed. Error: SyntaxError: Unexpected token e in JSON at position 1 at JSON.parse () Which syntax element am I missing? ASP.NET // Retrieve "tes ...

Error: The OOP class value for translateX in the Web Animation API is returning as undefined

I'm currently working on a basic animation project using JavaScript. I have utilized the Animation class from the Web Animation API. My goal is to create multiple instances of this class in order to animate different elements with varying values and r ...