3 ms·
I don't write Kotlin, but what that does (assuming I'm guessing at it correctly) requires far more awkward code in most other languages. That looks like it wil
by everforward 2y ago
I don't write Kotlin, but what that does (assuming I'm guessing at it correctly) requires far more awkward code in most other languages. That looks like it will allow you to extend the types of objects deep inside the library so that you could e.g. create your own Request object without having to type cast inside the HTTP handlers or wrap the entire library.
That shifts the complexity of doing that out of the runtime and into the Typescript preprocessor where it's not going to mess with your production instances.
I also don't think it's all that bad; it's a lot of generic types, but it doesn't appear to be doing anything particularly complicated.
I do think they get awful, though. This is something I've been hacking on that I'm probably going to rewrite https://pastebin.com/VszX3MyE https://pastebin.com/VszX3MyE It's a wrapper around Electron's IPC and derives a type for the client from the type for the server (has to have the same methods and does some type finagling to strip out the server-specific types). It also dynamically generates a client based on the server prototype. The whole thing rapidly fell into the "neat but too complicated to be practical" hole.
- dhruvrajvanshi 2y ago> I don't write Kotlin, but what that does (assuming I'm guessing at it correctly) requires far more awkward code in most other languages You're NOT assuming correctly. In Kotlin, this would be handled as an extension property on the Request type. You could write it just like normal code instead of extending some global ambient interfaces. val Request.foo: Bar = whatever get("/") { req.foo // just a method call } You can CMD+Click on it and read the actual implementation (instead of generated type definitions). The Typescript ecosystem needs these complicated types because of some design choices (no type based dispatch). I suggest looking up how other languages solve these problems. You'll find that in typescript, you have to reach for complex types far sooner than in other languages.
- everforward 2y agoSo if I pass that Request option to another function that expects a Request object, the compiler is going to track that I’m using an extended object instead of the actual Request type in the function signature and allow me to access the “foo” property? That’s what I’m specifically talking about. Yours is just dependency injecting a type, which is more avoiding the existing types in the library. That would be the “wrapping” option I was talking about. You don’t need to extend the types if you’re just going to dependency inject them. You could just have an entirely separate object that you pass around at that point.
- dhruvrajvanshi 2y agoIf the other method has visibility of my foo property, then it can call it. Nothing is being "injected" anywhere. It's the moral equivalent of foo(req). It's statically dispatched
- everforward 2y agoThat is exactly dependency injection, the functions have to be embedded into a scope that has access to additional values because the framework doesn’t support passing them directly. The types are injected into the function by being embedded into another scope. It’s not some kind of moral sin, but it is a kludge. The type system is now tied to the structure of your code, because scoping is now intrinsic to your types. It’s not the end of the world, I’ve worked in similar systems, it just tends to have a heavy mental overhead at some point as you now have to keep scoping in mind as part of your types.