> Slow debug cycle due to increased compile time. If using TDD, it takes longer to run tests. The delays adds up - Especially on large projects.

But you can have decreased tests because you have to test for common typing issues. A lot of my PHP tests are type-checks.

> Type definitions from DefinitelyTyped are often out of date or have missing properties/methods. It means that I can't use the latest version of a library.

I've had this happen with a very obscure library that was partially-typed by someone (god bless their soul) but it took me only a few minutes to manually make the changes to the definition.

> Doesn't guarantee type safety at runtime

That's not the purpose of the product though. It's like complaining you can't cook a turkey in the microwave; It's true, it would be a nice, but it certainly doesn't mean microwaves are bad -- they're just for a different purpose.

> Whenever I write any class/method, I have to spend a considerable amount of time and energy thinking about how to impose constraints on the user of the library/module instead of assuming that the user is an intelligent person who knows what they're doing.

Constraints? I would call it documentation. I'm sure you're users would appreciate knowing what methods your class has and what the parameters are.

> Compiler warnings make it hard to test code quickly using console.log(...); I'm more reliant on clunky debuggers which slows me down a lot and breaks my train of thought.

Tell TypeScript to always generate the JavaScript code even on type errors and then you don't have to let it slow you down.

> The 'rename symbol' feature supported by some IDEs is nice, but if a class or property is mentioned inside a string (e.g. in a test case definition) then it will not rename that; so I still have to do text search after doing a symbol rename and manually clean up.

I think it's a good reason to avoid storing identifiers in strings which is an anti-pattern in any language. Either way, you have this problem without TypeScript. Because it doesn't solve every problem that makes a poor excuse to keep it from solving some problems.

> It takes a lot of time think of good names for interfaces and they are renamed often as project requirements evolve. It's not always clear whether similar concepts should be different types or merged into one.

I agree totally! It's never been easier to refactor and rename than with a strongly typed language. Admittedly I haven't done too much work making these big changes in TypeScript but definitely have done it with C#/Java and compared to dynamic languages the speed you can make correct changes is amazing. You can see your mistakes as you type with good tooling.

> Setting up TypeScript is a pain.

I've setup a complete modern JavaScript tool setup and setting up TypeScript is by far the easiest part of that.

> Adds a lot of dependencies and complexity. It's a miracle that TypeScript works at all given how much complexity it sweeps under the carpet. Have you looked at the output JavaScript? Try to compile something that uses async generators and see what the output looks like.

That's what async generators do. They do the same thing in other languages (just look at the disassembly). It automates creating a state machine. I don't see why anyone would want to write a state machine themselves rather than let the compiler do it for you. It's actually difficult enough that most people wouldn't do it even though it's a great programming pattern.