Thank you for stopping by to answer @JeremyLikness! Really appreciate it. Let me put another way β I do not have the leverage (yet) to learn from senior developers because I don't have a developer job. And I have not fully experienced the pain points of Javascript without types because I haven't worked in a large codebase. So when I stumble upon something like this code (unstated reactjs state management library's code), I wonder what
state: $Shape<State>
does here, or what
...instances: $TupleMap<Containers, <C>(Class<C> | C) => C>
does here, unless I google about it and understand.
What I'm really trying to get an answer to is β that because my only way to learn is by reading code, how could I leverage types to the best of their capability when I do not know the full extent of their power (I mean I can't just sit down and start reading docs from start to end and expect myself to find aha! moments cited at the code lines which could leverage something particular, can I?)
I don't know if I'm making sense, but yes that is what is in my mind right now.
I'm a huge fan of typing because I've been on projects that started out with pure JavaScript, then moved to TypeScript, and saw 4x increase in velocity. This was with large projects (millions of lines of code) and large teams (dozens distributed around the globe) so mileage on a smaller project may vary.
We had many people who resisted the move, saying JavaScript had "everything we need" but quickly became converts after moving. In looking at the projects, interviewing the developers, and trying to determine why it was helpful, we came up with:
Discovery - intent of the interface is clear and easier for new developers to understand
Documentation - the libraries are self-documented with signatures and return values and IDEs can use these to help with auto-completion and development-time checking
Version safety - TypeScript follows upcoming standards so you can leverage the latest syntax and still backwards compile to legacy versions
Scope safety - lambdas or => operator helps unwind issues with "this"
These, in turn, enable us to scale the team and increase velocity.
As for "how to start from scratch" I think the idea is to look at intent. If you provide a method for multiplication, you aren't going to multiply strings to Booleans. So you tag in the input parameters with your numeric type (intent) and you tag your return value with a numeric type (intent). If you are doing a list operation, you can use generics to type the list operation and then your method that is called for each item has access to that type. Then it's easy to do some "dot completion" and discover in real-time what that type has available. As you have methods that you may want to mock for testing, you can leverage interfaces to describe the signatures and use these to implement different ways, or to pass in a function that implements a strategy.
I'm not sure if this is specifically what you are looking for but I have access to plenty of real world projects that benefited tremendously from TypeScript. In most cases the two results were fewer defects and faster velocity.