Creating custom generic functions such as IsAny and IsUnknown that are based on a table of type assignability to determine

I attempted to craft a generic called IsAny based on this resource.

The IsAny generic appears to be functioning correctly. However, when I implement it within another generic (IsUnknown), it fails:

const testIsUnknown2: IsUnknown<any> = true; // issue here, should be false

Interestingly, switching out the IsAny generic with the commented one resolves the problem. Why is this occurring? I can't distinguish any distinction between both versions of the IsAny generic, yet it seems that my implementation does not work within other generics.

// type IsAny<T> = 0 extends (1 & T) ? true : false;

type IsAny<T> = unknown extends T ? (T extends object ? true : false) : false;
const testIsAny1: IsAny<any> = true;
const testIsAny2: IsAny<unknown> = false;
const testIsAny3: IsAny<string> = false;
const testIsAny4: IsAny<object> = false;

// unknown is only assignable to two types: unknown and any
type IsUnknown<T> = unknown extends T ? (IsAny<T> extends true ? false : true) : false;
const testIsUnknown1: IsUnknown<unknown> = true;
const testIsUnknown2: IsUnknown<any> = true; // issue here, should be false
const testIsUnknown3: IsUnknown<object> = false;
const testIsUnknown4: IsUnknown<number> = false;

Answer №1

The issue arises with your isAny<any> function, as it returns a boolean, allowing both these assignments:

const testIsAny1: IsAny<any> = true;
const testIsAny2: IsAny<any> = false;

In contrast, the second definition of isAny makes testIsAny2 fail.

Your current implementation of isAny fails due to the conditional type T extends object ? true : false returning both options for any. To address this, you can rectify it by encapsulating both sides in square brackets (documentation reference):

type IsAny<T> = unknown extends T ? ([T] extends [object] ? true :  false) : false;

Experiment with the corrected implementation in the TypeScript playground.

Answer №2

The issue lies within the function IsAny.

You have observed that true: IsAny<any>, but also keep in mind that false: IsAny<any>.

You've brought up a point about conditional types that can be quite unexpected.

Let's consider this scenario:

type Extends<T, U> = T extends U ? true : false;

We get:

Extends<'a', 'a' | 'b'> =:= true
Extends<'c', 'a' | 'b'> =:= false

No surprises so far.

But here's where it gets interesting:

Extends<'a' | 'c', 'a' | 'b'> =:= boolean

When we use T extends U ? …, if there exists a subtype of T that is also a subtype of U and another subtype of T that is not a subtype of U, then the resulting type becomes a union of both possibilities.

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

Changing route parameters or query parameters does not trigger a reload of component data in React

The "home" component has links that direct to the product component when clicked. Another component always visible displays links to recently visited products. However, on a product page, these links fail to work properly. Although the URL updates and tri ...

What is the best way to position two elements floated to the right in separate rows within a single row?

Having trouble with a web design issue. I am currently working on a website and trying to format an input field with a label so that the label sits on top of the input while floating to the right. However, I'm encountering difficulties as the elements ...

Why am I unable to access all elements within the map function?

Hey there, I have a function related query. Whenever I try to access my data, I can only reach the first index of each array. For instance, I have 5 different images of PlayStation, but on my webpage, I am only able to see one image. How can I resolve this ...

Using vue-resource to intercept an ajax error and catching the "Uncaught (in promise)" exception

I am utilizing vue-resource to retrieve data from the server. In order to access the correct data, a user must possess a JWT token. If the token is invalid or has expired, a status code of 401 will be returned. Similarly, if a user attempts to reach a forb ...

nodemon and ts-node not working as expected, failing to automatically recompile

I have been working on creating a REST API using express+ts-node. Following various online tutorials, I managed to set everything up and when I run the app using npm run dev, it works perfectly fine. However, I am facing an issue where it is not automatica ...

Experimenting with a Collection of Items - Jest

I need to conduct a test on an array of objects. During the test coverage analysis of the displayed array, I found that the last object with the key link has certain conditions that are not covered. export const relatedServicesList: IRelatedServiceItem[ ...

Utilizing Express middleware to serve routes in Sails.js

I am currently working on a sails app where the routes and static assets are served from the root location, which is functioning properly. However, I am looking to integrate an express middleware to serve these routes and assets from a specific path. To s ...

Styling the elements that are next to each other using CSS

Hey there, what if I have HTML elements structured like this: <div> <div>Name</div> <div><input type="text" class="check"> <div>Age</div> <div><input type="number" class="check"></div> ...

Has anyone figured out the issue with Uplodify? It suddenly ceased to function

For some time now, I've been using uplodify without any issues. Unfortunately, as of yesterday, it suddenly stopped working. I'm at a loss as to what might have caused this sudden change. Could someone please offer me some assistance? I've ...

Customize the text for the material icon

Can I customize an icon by using the following code: import FiberNewIcon from "@mui/icons-material/FiberNew"; Is there a way to add custom text to the icon? ...

How can I create a top right profile button similar to Google using AngularJS?

I am looking to implement a floating button in the top right corner of my main screen. When clicked, I want it to open a card below with an arrow pointing towards the button similar to the one on . I am currently using Angular Material and have tried using ...

Navigation buttons that move the user either up or down the page

I am a beginner in programming and I wanted to create two buttons for my webpage. One button should appear when the page is scrolled more than 300px and take the user to the top, while the other button should be displayed immediately and scroll the user to ...

Trouble with scrolling on Kendo chart while using mobile device

I am facing an issue with multiple kendo charts on my website. These charts have panning and zooming enabled, but in the mobile view, they take up 100% of the width which causes touch events to not work properly for scrolling. I attempted to attach an even ...

Switch back and forth between two different function loops by clicking

I have implemented two sets of functions that animate an SVG: one set runs in a vertical loop (Rightscale.verticalUp and Rightscale.verticalDown) and the other in a horizontal loop (Rightscale.horizontalUp or Rightscale.horizontalDown). On clicking the SVG ...

The world of TypeScript generics and derived data types

I'm looking to streamline the process of calling multiple functions by creating a function that handles this task. These functions all require similar business logic and cleanup operations. function foo(arg: number) { // perform actions using arg ...

ReactJS experiencing issue with the functionality of the all-the-cities library

Encountering an issue where importing the library all-the-cities causes reactjs to malfunction and display the following error: TypeError: fs.readFileSync is not a function (anonymous function) C:myproject/node_modules/all-the-cities/index.js:6 3 | cons ...

Build a dynamic table by leveraging JSON with the power of JavaScript and HTML

I'm currently working on creating a table where information is stored and updated (not appended) in a JSON file using JavaScript and HTML. The structure of my JSON data looks like this: [{ "A": { "name": "MAK", "height": 170, ...

Having trouble getting the AJAX script to change the background in Internet Explorer?

I'm currently experiencing an issue with an ajax script. Here is the code I am using: <script type="text/javascript"> $(document).ready(function() { $('#savecolor').click(function(){ var myVar = 'data= ...

Vue JS Image Path

I have a Vue.js structure file that looks like this: --assets ----image ------my-image.png ------my-image2.png --components ----user ------userStart.vue To display the images using an array object, my code in userStart.vue is as follows: ...

Challenges with JavaScript objects while using d3.js

I have been working on rendering a map using d3 within an HTML page that is running on a django web framework. One of the examples I came across from d3's sample archives can be found at this link: http://bl.ocks.org/NPashaP/a74faf20b492ad377312 Upon ...