DEV Community

Discussion on: In Defense of Defensive Programming

Collapse
 
cipharius profile image
Valts Liepiņš • Edited

As for the safety of external input in TypeScript case, I want to suggest a third option - parsing the data.

There are some great articles on validating vs parsing. Validation is like poking the data at certain points of application to see if it seems alright, but that comes with a drawback of possibly not checking enough or checking already validated data over again.

Where parsing is like taking the data and transforming it to a concrete form, that other functions can work with. If the data can not conform to this form, that's erroneous data. Once the data is transformed to this specific datatype, it's safe to assume that it will be correct since you have ended up describing it with concrete type and type checker can ensure that it will be properly treated by rest of the code.

Specifically in TypeScript case, one would define the acceptable format of data using interface. So a parser would be any function, that can take raw data (string, other possibly invalid structure) and returns object that fulfills an interface.

Sources of inspiration:

Collapse
 
bytebodger profile image
Adam Nathaniel Davis

This is quite valid. And I've already noticed a few other comments referring to parsing. I myself have actually gone quite a ways down this road in some of my previous projects, and I think there's a definite time-and-place for this. But I don't think it's a use-everywhere kind of solution.

In TS, you can do this by creating classes that will, essentially, validate the data. And if the data doesn't conform, it throws an error or populates some kind of error state. Then you force the function to require an instance of that class. This is useful - but it still runs into a few problems:

  1. Like everything with TS, it's useless (nonexistent) at runtime.
  2. Dealing with the object that holds our value can sometimes be more annoying than simply having direct access to that value.

Granted, these aren't "deal breakers". But they're something to think about when considering the "parse in TS" approach.

Collapse
 
cipharius profile image
Valts Liepiņš

I'm coming with this idea from Haskell, so I wanted to try expressing it in TypeScript.
This is what I ended up with:

As for runtime safety, it's really up to how well one uses type system to enforce valid system state. The main constraint here is how expressive the type system is. I can't personally comment on limits of TypeScript, but from my little codepen expriment, it seems to be pretty capable.