I have grown rather weary of type systems that don't require you to be exhaustive and, for my money, types like `Omit` and `Pick` are nasty hacks that just let you pretend like you aren't doing dynamic types, something TypeScript does a lot. The TypeScript pattern of `someFunc<typeof someInput>` is just dynamic types with extra steps. Using `any` wouldn't really lose you much of anything, the "type" is just "whatever this input is". That's not a real type, that's a dolled-up dynamic type. But hey, it typechecks!
TypeScript's major weakness is that it doesn't want to break away from Javascript. That strict dedication to being a superset means the type system explodes into ten thousand builtin types the come, seemingly at times, from nowhere, simply to control for the wildness of Javascript. It feels like a joke sometimes, and like I need to have encyclopedic knowledge of all these highly-specialized types that are included in the language and are often being used in the background.
This leads to nearly impenetrable error messages regarding types, especially if you have a stack trace involving more than one object/record type (whatever you want to call it), it will expand all of them and just, no. It's unreadable. It can be read, but it cannot simply be grokked.
TypeScript just doesn't impress me. I get far better results from other languages for a whole lot less work. TypeScript claims to want a balance between correctness and productivity but the language gives me neither of those things. My typical experience is that I wrote almost the same amount of actual code, but now also with types. Elm lets me write far less total code. Less code means less bugs and more productivity, and better types and better correctness is what gives you those things.