TypeScript also allows me to refactor fearlessly, which substantially improves the quality of my code as I can do mini-rewrites without worrying about breaking interfaces.
I see this sentiment a lot but I honestly can't think of any non-trivial bugs that TS has caught for me. 99% of the bugs it catches I would see 1 second later when my page hot reloads and crashes.
Still even with TypeScript if types makes your functions ugly, then it shows the complexity of the code. Often it also suggests sensible refactoring that without types would not be apparent.
Javascript: "function area(left, top, right, bottom)"
In an editor the typescript function would likely be split into five separate lines.
"function area(
left: number,
top: number,
right: number,
bottom: number)
: number {"
None of the functions are complex but the the typescript function with the formatter creates a lot of noise.
If I'm working on a function foo(bar, baz), I know exactly what bar and baz are before looking at a single line of it, I've been tracing the code through to that function, how could I not know what the data types are at that point?
Your described experience is the rare exception when working with third party vendors, on long lived projects, or with teams that are not trivially small.
If I were to come up with environment where it is guaranteed to be a net positive it would be a company with lack of boundaries between teams and a lot of churn.
Essentially TS averages out engineers in your team. You're going to be slower, but more predictable. Your 10x engineers will become 5x, but 1x will become 2x.
It’s the other way around. For more experienced engineers TypeScript is a huge productivity multiplier: you can fly around a large code base with ease, making changes all over.
More experienced engineers also probably have some history with other statically types languages (perhaps Java, Swift or C++) so the concept of static typing is likely to be familiar to them.
For less experienced engineers, there are more drawbacks such as 1) additional language complexity and 2) possible unfamiliarity with static typing. Although TypeScript still a productivity boost because they are likely to have a higher error rate.
See, I've heard it multiple times. And yet nobody is able to provide evidence. Surely if effects are so huge it's should be easy to prove. We're commenting on the article that says TS is 10 years old. Where is the hard evidence?
When you ask about real examples of productivity boost, TS folks shift focus to bugs (why not talk about bugs in the first place?). When you ask about critical bugs, TS folks shift focus to IDE autocompletion. When you press for evidence, goal post is constantly being moved.
Whenever you see bold claims and no evidence other than personal stories for several years, you should immediately attribute it to placebo (or other biases).
> you can fly around a large code base with ease, making changes all over
Not really, unless you're talking about bloated codebases. Huge codebases are huge due to domain complexity, you can't be making changes all over without extensive testing. What does help is having a modular codebase with good boundaries. If you already have it, TS benefits are tiny. If you don't, you're better off spending time making it modular than switching to TypeScript.
> TypeScript still a productivity boost
And yet if you talk to popular library maintainers in Python/JS community, a lot of them say that types have slowed them down. Some of them still believe it was worth it, because it helps users of those libraries. But again, see how the goalpost is being moved?
Get off the high horse, static vs dynamic has been a never ending debate since the dawn of time.
Just because you side with one religion doesn't automatically make it "well known". Learn to recognize your own biases.
Here, enjoy the trivial search and read through links and their references:
https://www.google.com/search?q=Evidence+for+productivity+an...
I particularly enjoyed this comment:
https://softwareengineering.stackexchange.com/a/59668
Folks who think Dynamic Typing frees them of having to consider types are just fooling themselves; in this thread, even, the argument is that because they know what the types are then stating them is just unnecessary "noise". Which is all well and good, in the here and now, but provides no value when the code is foreign or forgotten; and with just a little additional syntax both the information is available to the programmer and the compiler can perform performance and security analysis with greater ease.
> for productivity, there's basically no measurable impact detected in studies, positive or negative
As I said, controversial at best.
But you're not being completely honest here. Most research is either inconclusive, or says dynamic is more productive. It is nearly impossible to find research that says static typing is more productive.
Which is quite obvious today, Uncle Bob and Steve Yegge were talking about this since 2000s.
https://sites.google.com/site/steveyegge2/is-weak-typing-str...
https://www.artima.com/weblogs/viewpost.jsp?thread=4639
> with just a little additional syntax
Unfortunately a little additional syntax easily turns into this:
f(): Array<Promise<ServerResponse.Response<Proto.Response>> | undefined> {...}
I didn't even get to the function body, and I already used multiple levels of my mental stack. Ugh.And gradual typing is the worst. It is either a terrible idea, or at least a terrible implementation (looking TS/mypy). It combines the worst of two worlds.
The only viable benefit of gradual typing is making dependency hierarchy explicit.
If the a team can distinguish between an average and excellent programmer's performance by the time it takes to read or write type information then I expect the skill and experience breadth within the team was already narrow.
Of course with a big, venerable project the balance changes drastically. But an experienced single-person project should be doable with javascript for a long while and may even get to MVP faster by focusing on things that are essential.
Now I’m addicted to it. Specifically the lightweight and easy to use _interface_ directive feeds my practice of self-documenting code with good doc and reusable data structures.
This is definitely sometimes not easy, and of course it'll get more difficult generally the more code there is or the more complex (usually meaning bad!) the design is, but I'd almost put it the other way round to your perspective - the types are like the signposts in this design evolution and discovery process. They don't make it easier to do the work of refactoring a design, but they do make it much easier to understand when I'm going in a good/bad direction and also when I have succeeded.
However TypeScript’s structural typing is much more flexible, because it is designed to describe the types of all the existing JavaScript code out there (via the DefinitelyTyped project).
This gives the best of both worlds: the freedom to express the architecture you need, plus the freedom to actually refactor an existing code base into that new architecture without introducing many bugs. Dynamically typed languages give you the former but not the latter.
In short, there is very little empirical data on this, and it’s almost entirely anecdotal. My gut feeling is that if typing were a huge benefit it wouldn’t be so hard to prove.
Edit: I should add that I think there are a ton of things that are far more important for a high performing dev team than types.
With TS you're paying the full price (in verbosity and complexity) but getting 10% of the value. There probably still are projects where it's a good deal, but my bet is they are the minority.
Some issues with TS are:
- There is no hard guarantee at runtime as everything is partially/optionally typed (including your deps).
- The types are not used to produce faster code at runtime (like in a compiled language).
It is almost like TS leaves half of the benefits of type checking on the table, obviously by design by being a JS superset.
You can get very close if you place fine-grained, well tested, type guards at IO boundaries, wrap poorly typed or overly dynamic dependencies, and have good discipline about internal boundaries. It’s a lot of work up front in a greenfield project, but it really pays off.
> The types are not used to produce faster code at runtime
Not directly, but in my experience good up front interface design tends to produce either immediately optimal JS (eg it tends to be monomorphic) or makes optimization much easier (as it makes any refactoring easier).
Edit:
> I like type systems as you can design with types and check things tie together before even running the code. This gives you very fast iteration cycles compared to CMD-R refreshing the browser/code.
I’d be remiss not to emphasize this! And not just skipping the reload cycle, it lets you skip a whole lot of test runs too. Type error in editor? Yep, those tests are gonna fail too.
Most typed languages don't have hard guarantees at runtime. With java, using reflection you can do all kinds of weird things at runtime. C++ has fewer guarantees because there is no VM and can't even introspect objects to see their real type. Dependencies are a real issue with TS, but many libraries are written in typescript and the type files are really robust.
>> The types are not used to produce faster code at runtime (like in a compiled language).
The V8 intepreter will actually do this at runtime. Usually it takes less than a second for v8 to optimize the javascript, and it will recognize that many functions and objects use the same interface and optimize appropriately. If you think about it the types only help so much because once you have the code graph, it becomes really easy to find the type and optimize the memory layout.
"Decent type systems" are usually in your way (especially if you want to quickly prototype something), and despite "decency" have abysmal tools (like "hey I've changed this function signature, update all call sites etc.)
[1] It's getting more and more complex, but even if you write something like this, it's still aiming to help you:
Partial<Record<typeof keyof SomeEnum, boolean>>>
I was reluctant to introduce a build step (having got used to the simple refresh cycle of a browser plus vanilla javascript) but I am pleased to say that this is a bit of a non-issue now with modern tooling like esbuild et al.
I still avoid NPM like the absolute plague, but the good news is that tooling like Deno have made typescript first server-side development in the ECMAScript world a total joy.
I've said it before - it's like floating through the air. So serene, so expressive. A true joy.