As do TypeScript, and Kotlin, and Dart, and Python (with MyPy), and C#, and Swift...
It's honestly inexcusable that Go, as a relatively new statically-typed language, doesn't have strict null-checks
As do TypeScript, and Kotlin, and Dart, and Python (with MyPy), and C#, and Swift...
It's honestly inexcusable that Go, as a relatively new statically-typed language, doesn't have strict null-checks
This isn't to say it's useless, just that it's not as useful as it _could_ be. I've seen codebases in all three languages where there have been real production issues due to null values, even though the type decls say otherwise. Kotlin probably does the best job here but using any JVM library introduces potential (K)NPEs.
Languages like Rust, Haskell or ML do not have this issue since they do not need to support such a legacy layer.
Still, typescript equips you to catch these errors, even if you can technically circumvent it. In practice it can be nearly bullet-proof if you follow good practices.
- !
- as x
- @ts-ignore
If you're using either a library that wasn't written in pure TS (maybe JS or JS with .d.ts) or interacting with some unconverted JS from your own codebase, you can easily pass a null through entirely by accident. The problem really stems from the JS end of things, but 9 times out of 10 you're going to be touching JS at _some_ level when using TS so I think it's fair to point out this gap.
You can override TypeScript's checks for anything, not just nulls, and yet people still get tons of benefit from it. Same goes with many of Rust's safety checks in unsafe { } blocks.
Additionally, languages like C# and typescript have to be a little more flexible because they added this feature after the fact. Go had plenty of opportunity to do it up front and not require any compromises, and it chose not to.
E.g. nullable types are not options - you can't "map" them (you can't invoke Select, Where etc). It's easy to "get value or default" (via operator `??`), but you can't do the other, equally frequent thing, of "apply transformation on value if not-null". Or... well, you can, but here's the syntax:
var newVal = val == null ? (resultType?) null : compute(val.Value);
instead of var newVal = val.Select(compute);Of course that doesn't fix all the other issues with null handling in C# (inconsistency between null references and null value types, inability to nest options, ...)