Hacker News new | ask | show | jobs
by __ryan__ 1091 days ago
Yes, “any” is a wart. And it’s a bad one.

The correct type for values you don’t know the type of (like the response of an API call) is “unknown”.

TypeScript does not provide the facilities you describe because there is not a one-size-fits-all solution to the cases that are possible and common in JavaScript.

It is left to the developer to decide how to validate unknown data at the boundaries of the API.

There are third party libraries that facilitate this in different ways with different trade-offs.

  The compiler actively lies to you about the types you’ll have at runtime.
I find this to be rare if you are using strict mode with proper TypeScript definition files for your platform and dependencies. Usually the lie is in your own code or bad dependencies when an “unknown” type (including “any”) is cast to a concrete type without being validated.

  In nearly any other typed language I have some deserialization mechanism.
Could you provide examples? I either don’t understand or I disagree.
2 comments

> Usually the lie is in your own code or bad dependencies when an “unknown” type (including “any”) is cast to a concrete type without being validated.

Yes, but one of those bad dependencies is the standard library.

When does the standard library lie in this case?
Things are `any` when they should be `unknown` or generic, mostly. Off the top of my head:

- `JSON.parse` and `.json()` on response bodies both return `any`.

- `JSON.stringify`'s `replacer` argument is of type `(key: any, string: any) => any`.

- `PromiseRejectedResult["reason"]` is `any`.

There are certainly many others.

> Usually the lie is in your own code or bad dependencies

The lie is almost always in an external API response from fetch (hence the complaint about “any” above).

> Could you provide examples?

Off the top of my head… Go’s stdlib json.Unmarshal and Rust’s Serde derive Deserialize.

The lie is when your code uses* the “any” value where a concrete type is expected.

I was misunderstanding your point with the deserialize.

Edit: “using” -> “uses”