Observables are used at many places in an Angular 13+ applications and we subscribe to them to get the data returned from them. Many developers finds it difficult to give proper data type to the data received from the observable and often end up using any data type.

example:

Suppose you have a service with a method returning an observable like this

@Injectable({providedIn: 'root'})
export class AppService {
    constructor(private httpClient: HttpClient) { }
    getUsers() {        
        return this.httpClient.get('https://jsonplaceholder.typicode.com/users')
    }    
}

Now, if you try to subscribe to it in your component like this

import { Component } from '@angular/core';
import { AppService } from './app.service';
import { User } from './core/models';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'howtoangular';
  users!: User[]; 
  constructor( private appService: AppService ) {
    this.appService.getUsers().subscribe( (data)   => {
      this.users = data;
    })
  }
}

Then at the place where you are assigning data into the users property, TypeScript may through an error like this

The ‘Object’ type is assignable to very few other types. Did you mean to use the ‘any’ type instead?
Type ‘Object’ is missing the following properties from type ‘User[]’: length, pop, push, concat, and 28 more.

If you then try to give the type to the data returned like this

this.appService.getUsers().subscribe( (data: User[])   => {
      this.users = data;
    })

then you may get another type of error like this at the place where you have given type to the data

No overload matches this call.
Overload 1 of 3, ‘(observer?: Partial<Observer<Object>> | undefined): Subscription’, gave the following error.
Type ‘(data: User) => void’ has no properties in common with type ‘Partial<Observer<Object>>’.
Overload 2 of 3, ‘(next: (value: Object) => void): Subscription’, gave the following error.
Argument of type ‘(data: User) => void’ is not assignable to parameter of type ‘(value: Object) => void’.
Types of parameters ‘data’ and ‘value’ are incompatible.
The ‘Object’ type is assignable to very few other types. Did you mean to use the ‘any’ type instead?
Type ‘Object’ is missing the following properties from type ‘User’: id, name
Overload 3 of 3, ‘(next?: ((value: Object) => void) | null | undefined, error?: ((error: any) => void) | null | undefined, complete?: (() => void) | null | undefined): Subscription’, gave the following error.
Argument of type ‘(data: User) => void’ is not assignable to parameter of type ‘(value: Object) => void’.
Types of parameters ‘data’ and ‘value’ are incompatible.
Type ‘Object’ is not assignable to type ‘User’.
The ‘Object’ type is assignable to very few other types. Did you mean to use the ‘any’ type instead?ts(2769)

This is the place many developers end up using any data type to to the data received from the observable like this

this.appService.getUsers().subscribe( (data: any)   => {
      this.users = data;
    })

The right way to solve this issue is, first set the return data type from the observable when we are making get request and give the same time inside subscribe like this

return this.httpClient.get<T>('')

....

this.getUsers().subscribe((data: T) => {})

Our previous example can be written like this

return this.httpClient.get<User[]>('')
...
this.getUsers().subscribe((data: User[]) => {})