DEV Community

Discussion on: The common misconception about TypeScript

Collapse
 
tgiddings profile image
Trevor Giddings

I think it's misleading to frame this as a matter of compile-time vs runtime type-checking. In this line:

const respJson: DummyResponse = response.data
Enter fullscreen mode Exit fullscreen mode

You are lying to Typescript. It's not clear that you're doing it, but you are. You tell Typescript that it's a DummyResponse, but it's not. It's akin to DummyResponse *respJson = (DummyResponse *)(void *)response.data in a language like C++.

A valid static type-checker verifies that if the inputs have the type that the programmer says they do, then there will be no type-related explosions. If the inputs are not as the programmer says they are, there's not much that any compiler can do to help. This isn't unique to Typescript -- it's universal. The issue is just that Typescript makes it very easy to lie about types without noticing. That's the important takeaway for people getting started with Typescript.

Collapse
 
narasimha1997 profile image
Narasimha Prasanna HN

If an application depends on data from an external source (like REST APIs etc), the best way to integrate that data with your code-base would be to convert that data into any of the native structure supported by the language, in Python/JS you directly deserialize the data to a Dict/JSON object respectively. In strongly typed languages, you would define a structure which contains all the fields and schema information, you would deserialize and then type-cast that data to a struct. The problem here is not about conversion, but how well your client is safe against changes in the structure of external data? Of course, this is unavoidable, but if atleast a client code would crash or report an exception rather than blindly ignoring it and executing the further steps, it would be more reliable.

Strongly typed languages (i.e those who respect types at runtime) would throw exceptions, it can be at any place, for example, in Go, if the JSON you are trying to de-serialize is not compatible with the structure you defined, it would throw an error, stopping it from being ignored accidentally, even if it is ignored there somehow, the computation on incompatible data-type would throw an exception/error. Which is not true in untyped languages, the type is inferred at runtime, which leads to undesired conversions and improper results, an exception is thrown only when there is no other way. (even adding undefined to 1 gives you NaN rather than throwing an exception)

As you said, the actual problem with typed languages is universal, also there is no solution, there wouldn't be any because there is no way we can infer the type of an external data, unless it provides some way or unless we define its type by ourselves.

The focus here is to explain how weak JavaScript is when it comes to Runtime type safety and how TypeScript is not a good solution when it comes to Type safety at runtime. So the only way is to validate the data explicitly irrespective of TypeScript or JavaScript. Also in the end, if you see there is a mention of Protobuf and GraphQL, these tools validate and throw errors at de-serialization phase itself, so you don't have to worry about validating explicitly, just like strongly typed languages.