Encountering an issue in Angular when utilizing BehaviorSubject<this> within a parent class and attempting to assign the type of a ChildClass to that

I'm facing a perplexing issue: my code runs smoothly in TypeScript strict mode but fails to compile in Angular. The trouble seems to stem from BehaviorSubject<this>; other generic typed fields do not pose any problems.

Below is the snippet of code causing the issue:

class SomeGeneric<T> {}

class BaseClass {
  /* comment or uncomment the line below */
  public thisSubject$: BehaviorSubject<this | null> | undefined;
  public thisPromise: Promise<this> | undefined;
  public thisSome = new SomeGeneric<this>();
}

class ExtClass extends BaseClass {
  public anotherField: number = 0;
}

function takesCtor(ctor: typeof BaseClass) {
  console.log(ctor);
}

takesCtor(ExtClass);

Upon inserting this code into an Angular project's source, the error message arises (specifically at the last line when trying to pass the child class constructor to a function that expects the base class constructor):

Argument of type 'typeof ExtClass' is not assignable to parameter of type 'typeof BaseClass'.
Construct signature return types 'ExtClass' and 'BaseClass' are incompatible.
The types of 'thisSubject$' are incompatible between these types.
Type 'BehaviorSubject<ExtClass | null> | undefined' is not assignable to type 'BehaviorSubject<BaseClass | null> | undefined'.
Type 'BehaviorSubject<ExtClass | null>' is not assignable to type 'BehaviorSubject<BaseClass | null>'.
Types of property 'observers' are incompatible.
Type 'Observer<ExtClass | null>[]' is not assignable to type 'Observer<BaseClass | null>[]'.
Type 'Observer<ExtClass | null>' is not assignable to type 'Observer<<BaseClass/null>.
Type 'BaseClass | null' is not assignable to type '<ExtClassnull'>.

Moreover, here is a segment from tsconfig.json:

  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "module": "ES2020",
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "ES2020",
    "typeRoots": ["node_modules/@types"],
    "lib": ["es2018", "dom"],
    "sourceMap": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true
  }

To explore further, I have provided a StackBlitz link featuring a minimal Angular application where the issue occurs: https://stackblitz.com/edit/angular-ivy-gmsfuf?file=src/main.ts

Additionally, you can find a StackBlitz link for a simple plain TypeScript project without the compilation issue: https://stackblitz.com/edit/typescript-dufytr?file=index.ts

The main query revolves around

How can I resolve the compiling issue faced in Angular when the same code works flawlessly in plain TypeScript? Which Angular package might be triggering this error? Considering it only occurs in one project and not the other, my assumption leans towards a package conflict or an Angular compiler option. Any guidance on where to begin investigating?

Answer №1

Avoid using this as a type. It is recommended to explicitly specify the type instead.

class BaseClass {
  /* comment or uncomment the line below */
  public thisSubject$: BehaviorSubject<BaseClass | null> | undefined;
  public thisPromise: Promise<BaseClass> | undefined;
  public thisSome = new SomeGeneric<BaseClass>();
}

You can see an example with the correct implementation here: https://stackblitz.com/edit/angular-ivy-ntrewa?file=src%2Fmain.ts,src%2Fapp%2Fapp.component.ts

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

"Incorporating the node_modules folder into the Express.js compilation process

Is there a way to automatically include dependencies during Express.js compilation, similar to building a React project? I want to avoid dealing with dependencies after the build process. Any suggestions on how to achieve this? I have not attempted any so ...

Navigating focus within form elements using Angular techniques

Purpose There is a form with various input elements (el1, el2 ...) el1 may or may not have initial focus when a keydown event occurs, the following actions should be taken: If none of the input elements are in focus, move focus to the first non-empty e ...

Using Selenium WebDriver with JavaScript: Handling Mouse Events (mouseover, click, keyup) in Selenium WebDriver

I am currently working on integrating Selenium testing for mouse events with dynamically generated elements. Specifically, I am attempting to trigger a "mouseover" event on an element and then interact with some icons within it. However, I have encountere ...

What is the best way to flatten a 2D array using TypeScript?

If I have an array structured like this: [0]: ["id_1"]: prop1: "abc" prop2: "def" ["id_2"]: prop1: "ghi" prop2: "jkl" [1]: ["id_3"]: prop1: "mno" prop2: "pqr" ["id_4"]: prop1: "stu" ...

What is the best way to securely store a JWT Token received from Cognito after logging in through the Cognito Hosted UI?

Our current architecture involves front end Angular and backend nodejs/express. This setup functions in the following order: User logs in to the site via Cognito Hosted UI Upon successful login, the user is redirected to our home page with a code sent in ...

What is the method for defining a mandatory incoming property in an Angular2 component?

In my current project, I am developing a shared grid component using Angular2 that requires an id property. export class GridComponent { @Input() public id: string; } I'm looking for a way to make the id property mandatory. Can you help me with ...

Retrieving the inner text of a dragged element using Angular Material's DragAndDrop feature

Can the inner text of a dragged element be retrieved and utilized in the "onDrop" function within Angular's cdkDragAndDrop feature? onDrop(event: CdkDragDrop<string[]>) { if (event.previousContainer === event.container) { moveItemIn ...

Unable to construct a node typescript project using solely production dependencies

I am currently working on a Node TypeScript project that utilizes various third-party libraries such as express. To ensure type safety, I typically install the @types/express module as a dev dependency following common instructions. The installation works ...

Pass values between functions in Typescript

Currently, I have been working on a project using both Node JS and Typescript, where my main challenge lies in sharing variables between different classes within the same file. The class from which I need to access the max variable is: export class co ...

The shop named 'someStore' is currently unavailable! Please ensure that it is being offered by a valid Provider

I'm having trouble setting up a new project using React, Typescript, and MobX. Despite having a relatively simple piece of code, I can't seem to get MobX to work properly. It keeps showing me this error message: Uncaught Error: MobX injector: S ...

I'm attempting to retrieve an image from the database to display in the modal, but unfortunately the image isn't appearing as expected within the modal

I have the following code snippet for fetching an image: <img src="pics/file-upload-image-icon-115632290507ftgixivqp.png" id="image_preview1" class="img-thumbnail" style="margin-top: 15px; height:50%; width:20%"&g ...

Issues with navigation in React Native Typescript

Currently, I am in the process of developing a new React Native Expo project utilizing TypeScript. I have been attempting to configure navigation following the guidance provided in React Native's TypeScript documentation. However, upon running and sim ...

Embed the value of an array in HTML

Upon running console.log, the data output appears as follows: {TotalPendingResponseCount: 0, TotalRequestSendCount: 1, TotalRequestReceivedCount: 1, TotalRequestRejectCount: 3} To store this information, I am holding it in an array: userData : arrayResp ...

How to troubleshoot: trying to assign '{ source: string; }' to type 'string' is not valid

I'm encountering an issue that seems like it should have a simple solution, but I can't seem to find any explanations on how to fix it. I'm working with Next.js and Typescript to create a component that displays an image and uses hooks to ma ...

Custom Mui table sizes - personalized theme

By implementing custom sizes for the Table component in Material UI, I have extended the Table size prop with the following declaration: declare module '@mui/material' { interface TablePropsSizeOverrides { relaxed: true large: true } ...

Angular 4 ngbtypeahead search filter

I am looking for a way to remove previous results from ngbtypeahead if the user does not select an option. Even when all characters are removed from the input text, the results should not be displayed. NgbdTypeaheadHttp.component.ts export class NgbdType ...

Outputting the square root of integers ranging from 4 to 9999

I'm looking to calculate the square root of all numbers up to 9999. Are there any ways to instruct the program to skip numbers that do not have a perfect square root? Below is the current code I am using: let i=1; for (i===1;i>=1 && i <10000;i ...

Create a new TypeScript object without any initial properties, then proceed to define its attributes

Working on honing my skills with Angular Forms utilizing the template-driven approach. My goal is to construct a user interface to display the output of my data in this structure: <hr> <div class="well well-lg"> ...

Sending an HTTP POST request from an Angular 6 application utilizing Sendgrid and a NodeJs Google Cloud Function results in a Error 405 message

Attempting to access an Email through Sendgrid from an Angular 6 application with minimal payload. Utilizing a Google Cloud Function for the request leads to a 405 error from the browser: 405 Blocked by CORS policy: Response to preflight request doesn&ap ...

What is the best way to iterate through an array and dynamically output the values?

I am facing an issue with a function that retrieves values from an array, and I wish to dynamically return these values. const AvailableUserRoles = [ { label: 'Administrator', value: 1 }, { label: 'Count', value: ...