Reputation: 330
The new HttpClient class in Angular 4.3 seems to return Object instead of any by default.
Is there a particular reason for doing that, given the typescript documentation says:
Don’t ever use the types Number, String, Boolean, or Object. These types refer to non-primitive boxed objects that are almost never used appropriately in JavaScript code.
https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html
I'm aware that I can provide my own return type using:
this.httpService.get<any>('/api1').subscribe(Data => {console.log(Data.Value1)});
It would seem to be easier to just make it the default. I'm aware that I can create a type specific for the data it's returning, but using any seems like it'd make it more flexible.
I was going to extend the HttpClient and override the methods to return any, but before I do that I wanted to see if there was something I was missing.
Upvotes: 10
Views: 5086
Reputation: 222354
The keyword in non-primitive boxed objects that are almost never used appropriately in JavaScript code is almost.
As explained in this answer, JSON document can be anything but undefined
and symbol, this makes Object
more suitable type than any
.
The behaviour of any
versus Object
is explained in the manual:
The any type is a powerful way to work with existing JavaScript, allowing you to gradually opt-in and opt-out of type-checking during compilation. You might expect Object to play a similar role, as it does in other languages. But variables of type Object only allow you to assign any value to them - you can’t call arbitrary methods on them, even ones that actually exist
any
response type allows to call arbitrary methods on it, which is not a desirable behaviour, including the ones that don't exist.
A suitable type for JSON response is
any[] | object | boolean | number | string | null
And a precise one (like is shown here, with the addition of null
) is:
type JSONValue = boolean | number | string | null | JSONObject | JSONArray;
interface JSONObject {
[x: string]: JSONValue;
}
interface JSONArray extends Array<JSONValue> { }
This is likely the way it should be done in HttpClient. While Object
is less accurate yet still more applicable type than any
.
Upvotes: 4
Reputation: 4862
Disclaimer: There are a lot of overloads available with all sorts of return types - so I may be reading more into this than I should.
I havent seen anything specific to back this up, but my guess is that its because Object
more accurately describes the type since its stricter than any
and "natively" associates with generic javascript object methods (see https://blog.mariusschulz.com/2017/02/24/typescript-2-2-the-object-type). In my humble estimation at least, this seems to fit the change to return the response body (as assumed JSON) by default.
See this question for a way more in depth comparison of Object vs any: TypeScript any vs Object
There is also a great article on HttpClient by Alligator.io here: https://alligator.io/angular/httpclient-intro/
TLDR:
...One major difference is that a JSON response is expected by default, so there’s no need to explicitly parse the JSON response anymore.
[Text in between removed for brevity]
By default the HttpClient returns the body of the response.
[More text removed]
If you expect something else than JSON as the response, you can specify the expected response type using an object with the responseType key...
I'd really recommend reading the whole article.
Upvotes: 3