Search code examples
typescripttype-safety

TypeScript Type-Safety in Node Apps


In a vanilla NodeJS tutorial I noticed the instructor always trying to define his variables in a way to guarantee no surprising assignments or values such as this one:

p.name = typeof (coinPair.name.toUpperCase()) === 'string' ? coinPair.name.toUpperCase() : false

I started to use this method in many of my codes to sort of guarantee if the value is not going to be assigned as expected it better be assigned to false (or some other specific default) so that it's easier to detect app crash reasons and avoid unexpected behavior.

When I started to use TypeScript, I realized its' native type safety features, which made me ask: Is the method used above still reasonable when using static strict typing my variables? Will it be useful when TypeScript already will not allow type changes during execution?

A developer I was discussing with was arguing that TypeScript transpiles to JavaScript at the end of the day, and claiming that its' type safety is only useful for debugging and that during runtime it's still javaScript without the TypeScript safety. He claimed that a variable defined as string with TypeScript may still accept a number (perhaps coercing even?).

I am confused now. Should TypeScript type safety measures suffice or I should still use the above method as necessary?


Solution

  • If you only use your code for yourself or your team and everything you or your team create is in TypeScript then you don't need those kinds of checks. Otherwise, if you are sharing, or plan to share your code it will need boundaries. Even code you don't write should have boundaries. Where these boundaries are and is a design and development decision. Some libraries have large boundaries (e.g. a language's standard library) and others have very small controlled boundaries.

    At these boundaries you may choose to do the above checks. As your peer claims, nothing in TS will protect you at runtime. If you created a TS module and publish it on NPM you should be publishing the JS. A JS developer can import/require your module and use it in their JS code and pass in whatever they want.

    Also, even if you were certain your callers would also be using TypeScript you could still have these kinds of boundary-checking issues. For example, checking if objects are undefined or null, making sure JSON passed in from a web request is valid, etc. However, JS is such a loose language that it tends to require fairly exhaustive boundary checks so it's no surprise you'd see them in TS tutorials as JS developers who migrated are pretty used to having to do them.

    At this point it probably gets opinion based. For example, I know many developers that sprinkle null checks exhaustively throughout a code base. In general I personally see this as a symptom of poor design and lack of awareness of boundaries. I am personally fairly against the idea of performing validity checks & asserts so that a bug is detected earlier. Such checks complicate the readability of code and reduce it's maintenance.