Error code TS 2322 reported in several HttpClient services following the transition from Angular 5.2 to version 6.0.7

Currently, I am in the midst of updating my project to Angular 6 with TypeScript version 2.7.0. Previously, in Angular 5.2.12, my service methods were written like this:

isPartDraft = (part: number): Observable<boolean> =>
  this._http.get(`${this.rest}/isDraft/${part}`)
            .catch(MyPartService.handleError);

The function definition was annotated with a return type, however, the type was not asserted within the function body.

Now, it appears that in certain scenarios, this approach is no longer valid as the tsc compiler throws the following error:

TS2322:
Type 'Observable<Object>' is not assignable to type 'Observable<boolean>'.
  Type 'Object' is not assignable to type 'boolean'.

As a result, I have to assert the return type within the function body, following the guidelines outlined in the current Angular documentation:

isPartDraft = (part: number) =>
  this._http.get<boolean>(`${this.rest}/isDraft/${part}`)
      .pipe(catchError(MyService.handleError));

Fortunately, everything seems to be working fine so far, despite the fact that we have not modified our annotations since angular2-rc6. However, it's possible that this issue has been present for some time.

Interestingly, I do not encounter any TypeScript errors in the following cases:

getPasswordPolicy(): Observable<PasswordPolicy> {
  return this._http.get(`${this.rest}/securityPolicy/`)
    .pipe(
      map((securityPolicy: any) => securityPolicy.passwordPolicy),
      catchError(error => observableThrowError(error))
    );
}

Similarly, in another service:

getPartsAtDate = (id: number, date: string, time: string): Observable<number[]> =>
  this._http.get(`${this.rest}/partsOnDate/${id}/${date}/${time}`)
    .pipe(catchError(MyService.handleError));

getAllNewOrders = (id: number): Observable<Orders[]> =>
  this._http.get(`${this.rest}/${id}`)
    .pipe(catchError(MyService.handleError));

This raises the question of how the pipe(), catchError(), and map() operators are interacting to cause this inconsistency. Why is it that I cannot annotate the function definition in the first case, but can do so in the latter three?

Instead of blindly fixing the errors pointed out by tsc, I am eager to comprehend the underlying issue, especially given the different outcomes in seemingly identical situations.

For reference, here is the implementation of the error handler (which is the same in each service):

private static handleError(error: any) {
  console.log('error ' + error);
  return observableThrowError(error.status || 'Server error');
}

Answer №1

In your first example, the get method is overloaded and may not always use Generics. The signature chosen depends on how get is called, resulting in the return type of Observable<Object>. To obtain a different type of observable, you must utilize generics, such as get<boolean>.

But why do the other examples function correctly?

map((securityPolicy: any) => securityPolicy.passwordPolicy),

This snippet explicitly converts the type from Observable<Object> to Observable<PasswordPolicy>. If the syntax was

map((securityPolicy: SecurityPolicy
, it would not work.

Unlike map, catchError does not alter the observable's type in your situation, so it remains Observable<Object>.

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

Trouble detecting type definitions in Typescript typeRoots

I'm incorporating TypeScript into my project. When I attempt to bring in a package using commonJS const { v4: uuidv4 } = require('uuid'); No errors occur during compilation. However, when I transform it into an ES6 module like this: import ...

"Encountered a 401 error when attempting to call the second

While working on my spring application, I encountered an issue with returning information to my angular client. Initially, sending a request to '/login' and then an HTTP-post request to '/user' were successful. However, the second call ...

Is there a more efficient method to tally specific elements in a sparse array?

Review the TypeScript code snippet below: const myArray: Array<string> = new Array(); myArray[5] = 'hello'; myArray[7] = 'world'; const len = myArray.length; let totalLen = 0; myArray.forEach( arr => totalLen++); console.log(& ...

The error "Property 'user' does not exist on type 'Session'." occurred while attempting to pass session data using express-session and accessing req.session.user

I'm currently working on creating a basic login form for users to access a website, where I plan to store their session data in a session cookie. The express-session documentation provides the following example for setting it up: app.post('/login ...

Ensuring type signatures are maintained when wrapping Vue computed properties and methods within the Vue.extend constructor

Currently, I am trying to encapsulate all of my defined methods and computed properties within a function that tracks their execution time. I aim to keep the IntelliSense predictions intact, which are based on the type signature of Vue.extend({... Howeve ...

Accept an empty string as the defaultValue, but disallow it during validation using Zod, react-hook-form, and Material UI

Currently, I am working with material ui components alongside react-hook-form and zod validation in my project. One of the challenges I encountered is with a select field for a bloodType: const bloodTypes = [ "A+", "A-", "B+", ...

What is the best way to recycle a single modal in Ionic?

Apologies for the vague title, but I'm facing an issue with creating a single modal to display data from multiple clickable elements, rather than having separate modals for each element. For example, when I click on item 1, its data should be shown in ...

Angular SwitchMap is a powerful operator that allows you

I am currently utilizing the mat-table component from angular material, in conjunction with pagination features. Whenever a user inputs text into the search field, a filter method is activated to send the text, page size, and current page to the backend f ...

I am looking to trigger the change event from within the click event in Angular

My objective involves detecting when the cancel button is clicked while a file is being uploaded. I am trying to accomplish this by triggering the click event, then monitoring for the change event. If the change event occurs, the document will be uploaded. ...

Issue: The inject() function can only be executed within an injection context

Even after following the most recommended solutions online, I am still facing an issue that says Error: inject() must be called from an injection context. In addition to this error, I am also receiving multiple warnings such as: Warning: ###/src/ap ...

What is the best way to create an array of strings that can include multiple elements from a set of strings?

Exploring different roles for authorization: ['admin', 'manager', 'user'] Is there a way to create a specific type, named Roles, which is essentially a string array ( string[] ) that is limited to only containing values from ...

Having trouble downloading both an HTML file and a PDF file at the same time by clicking two separate buttons in an Angular 8 web API controller

I am encountering an issue with downloading files from my web application. I have two buttons - one for downloading a PDF file and another for downloading an HTML file. The problem arises when clicking on the link to download the HTML file first, as it do ...

Compiling a list of products, but the user interface needs some adjustments

Currently, I have designed a product list menu that includes a hover dropdown feature. This means that when a user hovers over a specific menu item, the corresponding list will automatically appear. However, I am facing two issues with this setup. Firstly, ...

How to vertically align Material UI ListItemSecondaryAction in a ListItem

I encountered an issue with @material-ui/core while trying to create a ListItem with Action. I am looking for a way to ensure that the ListItemSecondaryAction stays on top like ListItemAvatar when the secondary text becomes longer. Is there any solution to ...

Expanding the Mui Typescript breakpoints within a TypeScript environment

Encountering a typescript error when attempting to utilize custom names for breakpoint values: Type '{ mobile: number; tablet: number; desktop: number;}' is not compatible with type '{ xs: number; sm: number; md: number; lg: number; xl: numb ...

Upon updating AngularFire, an error is thrown stating: "FirebaseError: Expected type 'Ea', but instead received a custom Ta object."

I have recently upgraded to AngularFire 7.4.1 and Angular 14.2.4, along with RxFire 6.0.3. After updating Angular from version 12 to 15, I encountered the following error with AngularFire: ERROR FirebaseError: Expected type 'Ea', but it was: a c ...

`How can I extract HTMLElements from slots in vue3?`

When attempting to develop a Layer component, I encountered some challenges. Here is the code: // Wrapper.vue <template> <slot v-bind="attrs"></slot> </template> <script lang="ts" setup> import { defi ...

The cloud function that is callable is currently inactive and encountering errors upon invocation

I am experiencing issues with my Cloud Function which is supposed to call a request to the URL passed to it. This is my first time using TypeScript to make a request, so I added some print calls to troubleshoot the problem. However, the first log never app ...

Issues with the ionViewDidLoad() function?

Having some trouble implementing Email Authentication in my project. The method ionViewDidLoad is not being recognized. I also tried using the method ionViewWillLoad() but that didn't work either. Any ideas on what might be causing this issue? Here&a ...

What is the best way to create a dynamic sitemap in Next.js version 14?

I've encountered an issue with the code snippet I'm using for a dynamic sitemap on my blog post website built with Next.js 14. While it works perfectly fine in development, it fails to generate a dynamic sitemap in the build or production environ ...