Live data from Hacker News

Learn how to unleash the full potential of the type system of TypeScript

type-level-typescript.com

131–140 of 256 posts

Re: Learn how to unleash the full potential of the type system of TypeScript

#131

One of the worst things about Next.js, Remix etc. is their file system driven routes. I really wish these frameworks would stop relying so much on hidden magic. Conventions are good, but as to why those conventions aren't in code is quite peculiar. Previously, I wrote my route definitions with types for both path params and query params in one file, and used TypeScript to enforce that the equivalent back-end definiti…

remix-routes and next-type-safe-routes both allow for tacking on type safety here with a build step, not ideal but 90% of the benefit from that.

Re: Learn how to unleash the full potential of the type system of TypeScript

#132

A great idea. Now, everyone that learns this stuff, show some restraint! The drawback of a powerful type system is you can very easily get yourself into a type complexity mudhole. Nothing worse than trying to call a method where a simple `Foo` object would do but instead you've defined 60 character definition of `Foo` capabilities in the type system in the method signature. Less is more.

Also typescript doesn't always infer things thoroughly with generics and deeply nested types, so I’ve ended up avoiding them when possible. Performance also explodes if you have too much unions and stuff. Beware! Definitely some popular libraries out there that went overboard and nuke compiler performance for minimal gain.

Re: Learn how to unleash the full potential of the type system of TypeScript

#133

One of the worst things about Next.js, Remix etc. is their file system driven routes. I really wish these frameworks would stop relying so much on hidden magic. Conventions are good, but as to why those conventions aren't in code is quite peculiar. Previously, I wrote my route definitions with types for both path params and query params in one file, and used TypeScript to enforce that the equivalent back-end definiti…

remix-routes and next-type-safe-routes both allow for tacking on type safety here with a build step, not ideal but 90% of the benefit from that.

Looks like remix-routes is using string literals, which can be a pain for refactoring and jumping to usages etc. But it's certainly better than nothing. I'll give it a go. Thanks!

Re: Learn how to unleash the full potential of the type system of TypeScript

#134

A great idea. Now, everyone that learns this stuff, show some restraint! The drawback of a powerful type system is you can very easily get yourself into a type complexity mudhole. Nothing worse than trying to call a method where a simple `Foo` object would do but instead you've defined 60 character definition of `Foo` capabilities in the type system in the method signature. Less is more.

The types in your code are just as designed just like any other aspect of it. It's not a matter of restraint, it's a matter of doing things on the correct way.

I definitely know what you mean. There is usually a type that is "just right" in terms of rigidity and flexibility.

The reasons OP encourage restraint might be the mental overhead of understanding what's "correct", as well as needing to rely on not only yourself but other people to be correct.

Sometimes simple is faster and harder to screw up.

Re: Learn how to unleash the full potential of the type system of TypeScript

#136
post #75

Earlier quoted context omitted.

This is so true. I've been thinking recently that in the same way that "use boring technology" is a pretty well-known concept, so should "use boring types" enter the collective conscious. Type operators are exciting and flashy, but I found that using them too much leads to brittle and confusing types. Saving them for a last resort tends to be the right strategy. Often there's an extremely dumb way to write your types…

Agreed! Boring interface definitions is my rule for typing. I see way too many folks trying to use Omit (…) and Partial (…) creating absolute typing monstrosities. Feels like typing duct tape and it’s impossible to read the type definition when it’s generated in a tooltip.

Although to be fair, lack of visibility in the tooltip seems like a problem with the tools not with types. Many times I’ve wished I could tell TS to expand the next level of type signature.

Re: Learn how to unleash the full potential of the type system of TypeScript

#137

Earlier quoted context omitted.

OO programming is a very versatile paradigm, and not at all incompatible with JS/TS. It comes down to choice; pick one for the project and be consistent. That’s all that matters. DI does not require OOP, and you don’t need DI to write good TS/JS code. DI is common in OOP, but if you aren’t using OOP you don’t need DI anyway.

I successfully used functional programming with DI and it was quite pleasant! Because DI is just “give me the dependencies I need when I declare I need it” you can use simple classes as scopes similar to CQRS patterns and continue doing functional programming from there. It’s quite neat how you can interchange between the two and have it work rather nicely. Technically, you could even do the same thing with closures…

Do you mean something like this: f(arg1, arg2, arg3, deps)?

Re: Learn how to unleash the full potential of the type system of TypeScript

#138

Might as well ask here. On our teams, we have the occasional developer that is insistent on using Typescript in an OO fashion. This has always struck me as square peg round hole. Even though I come from an OO background, Typescript strict settings really seem to push me in a direction of using interfaces and types for type signatures, and almost never classes, subclasses, instantiated objects. I don't have a very goo…

>I don't have a very good answer for "yeah, but what about dependency injection"? though. Any thoughts from anyone? There is no "dependency injection" in a functional world, take this opportunity to show your colleague how FP makes their life easier. It's just a function. Instead of a class, implementing an interface, created by a factory, requiring a constructor, all you need is a function. Anything that was previou…

I think the problem with DI is less about how they are passed in and more about how usually there is are only two implementations: the real one and a test one. The test one is a mock/stub based on assumed behaviours of the real thing. Obviously, such an approach is essential in some situations but in general it is mostly bad.

Re: Learn how to unleash the full potential of the type system of TypeScript

#139
post #93

Earlier quoted context omitted.

True that. Once types get so complex, I’ve no idea what’s going wrong. Today I had code running fine but throwing errors all over the place because some deeply nested type mismatch between two libraries. I just any’d it… i aint got no time for that shit

But would the code really work without the type checking?

Are types always correct?

Re: Learn how to unleash the full potential of the type system of TypeScript

#140

A great idea. Now, everyone that learns this stuff, show some restraint! The drawback of a powerful type system is you can very easily get yourself into a type complexity mudhole. Nothing worse than trying to call a method where a simple `Foo` object would do but instead you've defined 60 character definition of `Foo` capabilities in the type system in the method signature. Less is more.

My coding philosophy is centered around simple interfaces. I think of power sockets and plugs. The simpler the socket/plug design, the easier it is to plug in. It's easier to connect a European plug which has 2 round pins than it is to connect a UK plug which has 3 rectangular pins at different angles. You can imagine how difficult it would be to connect a plug with 10 pins; it would be difficult to get the alignment right and you would have to push hard and fiddle quite a bit to get it all the way in.

If you can get a module to do the same thing with a simpler interface, then that's generally a better module; it's typically a sign of good separation of concerns. Complex interfaces are often a sign that the module encourages micromanagement of its internal state; a leaky abstraction.

A module should be trusted to do its job. The only reason a module would provide complex interfaces is to provide flexibility... But modules don't need to provide flexibility because the whole point of a module is that it can be easily replaced with other modules when requirements change.

Post reply on HN