Discovering the type of a generic class in TypeScript

Class B extends a generic class A, and I am trying to infer the generic type of A that B is extending. The code snippet below demonstrates this.

In earlier versions of TypeScript, this worked correctly for me. However, in my current project using version 3.2.4 (I also tried the latest 3.4.5), the inferred type now returns {} instead of string.

Any thoughts on what might be causing this issue? Could there have been changes that affect this behavior?

class A<T> {

}

class B extends A<string> {

}

type GenericOf<T> = T extends A<infer X> ? X : never;

type t = GenericOf<B>; // currently results in {}, when expected string

Answer №1

When a class contains a generic that is not utilized within the class itself, it essentially resembles an empty structure like {}, which triggers inference. The recent change that caused your code to malfunction was actually a bug fix, but you can solve this issue by incorporating "A's" generic somewhere inside the class. By doing so, the inference process will resume functioning correctly.

I hope this explanation helps clarify things for you.

class A<T> {
    hello: T = "" as any; // I have included the generic type within the class body.
}
class B extends A<string> {}
type GenericOf<T> = T extends A<infer X> ? X : never;
type t = GenericOf<B>; // This will result in 'string'.

Answer №2

After conducting extensive research, I finally figured out the solution on my own. It appears that TypeScript struggles to differentiate in this scenario due to the fact that all the classes are empty and essentially equivalent to {}. Simply adding properties is not sufficient; they must actually reference the generic T for TypeScript to infer the generic type correctly later on:



class A<T> {
  constructor(public a: T) {}
}

class B extends A<C> {
  constructor(public b: C) {
    super(b);
  }
}

class C {
  constructor(public c: string) {
  }
}

type GenericOf<T> = T extends A<infer X> ? X : never;

type t = GenericOf<B>;

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

NextJS - The server attempted to execute the find() function, which is only available on the client side

When attempting to utilize the .find method within the server component, I encounter an error. export async function TransactionList() { const transactions = await fetch('/transactions'); return ( <ul> {transactions.m ...

Guide to invoking the API prior to shutting down the browser window in Angular4

Currently, I am working on an Angular 4 application that consists of 5 components. My goal is to trigger an API call when the user closes the browser window from any one of these components. However, I have encountered an issue where the API does not get ...

What is the functionality of the node class within a doubly linked list?

Within the Node class, the next property can only be assigned a value of type Node or null. class Node { value: any; next: Node | null; prev: Node | null; constructor(value: any) { this.value = value; this.next = null; this.prev = null ...

Error in React-Typescript: The element type 'Component' is missing any construction or call signatures

I recently wrote a higher order component using React withContext: import React from 'react'; import permissionContext from 'context'; interface Props { Component: () => React.Component; } const withContext: React.FC<Props> ...

Can the type of a prop be specified in the parent component before it is passed down to the children components that utilize the same prop?

In my codebase, I have a component called NotFoundGuard. This component only renders its children if a certain condition is true. Otherwise, it displays a generic fallback component to prevent redundancy in our code. I am trying to figure out if there is ...

What is the correct method for storing a response in an array variable in Angular?

I am looking to save the response data from an API call in a variable and display it in the component.html file. Component.ts file : public coinsHistory = []; this.service.getCoinsHistory().subscribe( (response) => { this.handleCoinsRespon ...

Having Trouble with Angular Route (6) Configuration

I've been experiencing some unusual issues with the Angular 6 router, but this particular one is really frustrating. Here are the routes that I have defined in routing-app.module.ts: export const routes: Routes = [ { path: 'login&a ...

Testing the Angular router-outlet using Jasmine

When testing web-app navigation using Jasmine spec with RouterTestingModule, I am facing challenges with nested fixture.whenStable().then(() => {}). For instance: After clicking on multiple links where the router-outlet changes the displayed component ...

Discover the use of dot notation for accessing nested properties

In the deps array below, I aim to enforce type safety. Only strings allowed should be in dot notation of ${moduleX}.${moduleX service} // Modules each have a factory function that can return a services object (async) createModules({ data: { factory: ...

What is the solution to fixing a 400 bad request error in Angular Routing?

Encountering an issue on a particular route where a 400 error is displayed in the screenshot every now and then. It seems to work fine for a few minutes after deleting cookies, but the error resurfaces after accessing it multiple times. Other routes are fu ...

Leveraging TypeScript to sort and extract specific elements from two arrays

Given two arrays, I am looking to identify the elements in array2 that match elements in array1 based on a specific property. The arrays are structured as follows: var array1 = [ {"myId": 1, "text": "a"}, {"myId& ...

Is there a TypeScript rule called "no-function-constructor-with-string-args" that needs an example?

The description provided at this link is concise: Avoid using the Function constructor with a string argument to define the function body This might also apply to the rule missing-optional-annotation: A parameter that comes after one or more optiona ...

Trouble with querying NG elements using "queryAll(By.css)" in Angular and Jasmin unit testing

I've encountered an unusual problem that needs to be resolved for me to successfully complete a unit test for a project I'm currently engaged in. Here is what my unit test currently looks like: it('should display the navbar list', ...

Effortlessly collapsing cards using Angular 2 and Bootstrap

Recently delving into Angular 2 and Bootstrap 4, I set up an about page using the card class from Bootstrap. Clicking on a card causes it to expand, and clicking again collapses it. Now, I want to enhance this by ensuring that only one card is open at a ti ...

The specified argument, 'void', cannot be assigned to a parameter that expects 'SetStateAction | undefined'

Currently, I am engaged in a TypeScript project where I am fetching data from an endpoint. The issue arises when I attempt to assign the retrieved data to my state variable nft using the useState hook's setNft function. An error is being thrown specif ...

React hook triggering re-render

A function has been implemented to retrieve and decode user claims from a token stored in local storage using a hook. export const useActiveUser = (): { user: IUserTokenClaims | null } => { const [user, setUser] = useState<IUserTokenClaims | nul ...

Empty initial value for first item in array using React hooks

My goal is to store an array that I retrieve from an API in a useState hook, but the first entry in my array always ends up empty. The initial array looks like this: (3) ["", "5ea5d29230778c1cd47e02dd", "5ea5d2f430778c1cd47e02de"] The actual data I recei ...

Translate from one category to a different one

I often encounter a common issue - how can I efficiently convert one type to another? For instance, extending an object received from the server with UI-specific properties. interface RawData { id: number someOtherData: string } interface ViewData ex ...

How can Material UI React handle long strings in menu text wrapping for both mobile and desktop devices?

Is there a way to ensure that long strings in an MUI Select component do not exceed the width and get cut off on mobile devices? How can I add a text-wrap or similar feature? Desktop: https://i.sstatic.net/lo8zM.png Mobile: https://i.sstatic.net/8xoW6. ...

Taking advantage of Input decorator to access several properties in Angular 2

I am currently working on a component that is designed to receive two inputs through its selector. However, I would like to make it flexible enough to accept any number of inputs from various components. Initially, I tried using a single @Input() decorator ...