Hacker News new | past | comments | ask | show | jobs | submit login

- Documentation. You don't need to have free-text comments saying "@param myArg must be a string", you can just look at the type signature, and immediately know how to use a function. Attempting to pass in a number will fail at the time of writing, not at runtime (of your test). This is a huge benefit when using third party libraries. For a JS lib, you need to read the documentation, and if something is undocumented you need access to the source code and the time to analyse it, to understand exactly how to use the lib. Compare this to making the type interface available.

- It's easier for a machine to read, which means the possibility for better tooling. e.g. linters and checkers, automatic refactoring.

- It's actually faster to write, due to the ease of making changes. If you move a function out to a new module, the compiler will immediately tell you all of the invocation sites that are now broken. (If you rely on tests, you have to make sure you have tests in every invoking module, rather than just the module you are actually changing. [Ignoring mocking issues...])




I'm not so sure about the "faster to write" since my IDE and linting will already take care of that. The java-style boilerplate is a huge turnoff for me, and the validation seems to produce false negatives so often as to actually introduce more bugs. Ie, If a variable gets mutated without changing type, TS is now worse than useless for validation.

The self-documenting part is the strongest argument I've heard, but writing real documentation and real tests still seems better.


An IDE can assist you even better when it can understand the code you're writing. For example, autocomplete "myString.re" without type hints, and an IDE like IntelliJ might suggest the method "reject()" (which is found on a Promise interface), or "remove()" (which is found on a DB entity interface), as well as "replace()" (which is found on a String interface). Wouldn't it be nice for it to always pick the right option?

TypeScript doesn't help with immutability at all. For that, you should look at something like PureScript. (Or GHCJS, or any other compile-to-JS languages that support immutability.) TypeScript assumes you are sticking with JavaScript's semantics, mutability and all. If you want immutability, you still need to use "Object.freeze()". Variable mutation is not something picked up by types alone.

There are other languages that introduce "dependent types", which can actually include values in their type signatures, which might be able to specify something like you want; i.e. "a function that accepts an argument of type 'a' which derives a number, and returns the same type 'a', but the returned value must be equal to the input value plus 10".

Documentation is nice... or so I've heard! Speaking for myself, developers are lazy and just want to write code. Why not make them document the code as they write it? Plus, external documentation (even as JavaDoc-style comments) always falls out of date with the code.

I think better than tests, is to enforce "design by contract" - assert your preconditions and postconditions on every function. This inlines your assumptions and behaviour verification with the actual code to be run. (If performance is a concern, you can implement this in a way that allows you to disable assertions.)

In general, the more guarantees you can enforce at compile time (such as only accepting certain types of values, or that input values are never mutated in place), the less need there is for having twice as much testing code as application code.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: