5 ms·
I'll agree, and disagree. I made a similar comment in 2019 about "TS pushes you towards simpler APIs" [0], so I agree that it's both a good thing in principle,
by acemarke 4y ago
I'll agree, and disagree.
I made a similar comment in 2019 about "TS pushes you towards simpler APIs" [0], so I agree that it's both a good thing in principle, and something TS usage leans towards in practice.
At the same time... JS _is_ a very dynamic language, library design reflects that, and library code by its very nature must account for the different ways that users will want to call it. That causes library types to be much more complex than app types.
[0] https://blog.isquaredsoftware.com/2019/11/blogged-answers-learning-and-using-typescript/#typescript-pushes-you-towards-simpler-apis https://blog.isquaredsoftware.com/2019/11/blogged-answers-le...
- bwestergard 4y ago"JS _is_ a very dynamic language, library design reflects that" I would argue it should not. If your API cannot be well expressed in the Typescript type system, it is your API that should change.
- cogman10 4y agoYup. Especially since types are documentation. If you are using some meta dynamic type garbage, then I as a user of the API am left to wonder "Ok, this takes <U, K extends keyof U>... WTF is it expecting?" This isn't to say that sort of thing is ALWAYS wrong, but rather it should be the exception and not the rule. You do types because constraints make code clearer. By having a BF compiler in the middle of your template definition, you've defeated the types and you might as well put an `any` there with docs that say "here there be dragons!"
- hmsimha 4y agoThis is all well and good until you have to deal with other code and other APIs in your library (results from network requests, localstorage, untyped javascript libraries, etc.)
- naet 4y agoI'd rather not warp my whole project around a typing system if I don't need to. I also might not be the owner of every API I need to consume... I think TS is great in certain cases- I love being able to get intellisense info from TS. When I download a new library and I get those helpful hints built right in from the libraries TS adoption, I love it. Typescript in this instance is reducing friction in my development workflow. In my day job I work at an agency where we rapidly deliver a lot of new web properties. I have used Typescript on projects when it was a client requirement, but in our environment using Typescript generally feels like it overall adds friction and time to the project. Some team member inevitably gets stuck spending a bunch of extra time working with TS stuff: setting up the project with proper rules, writing some complex interface to deal with some random API we are either consuming or creating ourselves (in which case it is usually under rapid prototype development and needs to be updated constantly), etc. I'm sure it is very helpful when working at scale with tons of developers on a highly stable and established project, but in my opinion it isn't generally applicable to every web property that it would be better on Typescript; it really depends on the scale of the project and the scale of the team maintaining it.
- crabmusket 4y ago> I'd rather not warp my whole project around a typing system if I don't need to. This sounds to me like MongoDB advocates like "psh! who needs a schema! don't slow me down, I'll just dump JSON into the database however I like." The types exist whether you write them down or not. I agree with you that TS might not be great for everyone and every use case. But maybe you should just use `any` some more!
- jd_mongodb 4y agoEvery field in a MongoDB document (we encoded documents in BSON at the driver level) is typed and you can apply a schema to any collection if you choose to do so.
- deleted 4y ago[deleted]
- 323 4y agoPython is also very dynamic, yet libraries rarely allow arguments to be number/string/list/dict/function at the same time. Yet in JavaScript I see this all the time - pass a string URL, but we also accept a function which will return a string URL, or maybe an option object - { url: string, strict: boolean } So I think it's more of a culture thing.
- nicoburns 4y agoLuckily these types are not complex at all to type in Typescript. You just enumerate all the options with a | character separating them.
- 323 4y agoRight, but people compose. They take this union and put it in another object, which also allows multiple types for some field, and then they take that object and put it in another one, and then you have a 10 line type declaration for 3 fields.
- isbvhodnvemrwvn 4y agoWhich is why you can have aliases for those types, each level of abstraction can be nicely wrapped up. It just describes the reality.
- deleted 4y ago[deleted]
- eyelidlessness 4y agoI’m mostly sitting this out, but I’ll interject here because this is wrong. Union types are often used as an XOR (a | b as “either a or b, but not both”), but they’re an inclusive OR (Partial<a> & Partial<b>, as “some parts of a or b, the parts they share guaranteed”) which is almost never what anyone wants when dealing with objects. The pain is that you can’t distinguish them without a narrowing factor, and if you can’t the types are horridly complex.
- msie 4y agoYikes! Why bend over so much for clients of the library?
- Joker_vD 4y agoBecause the whole point of a library is to be useful to its clients.
- folkrav 4y ago> JS _is_ a very dynamic language, library design reflects that This is mostly an issue if you're tacking on those types on top of your existing design, rather than starting your design from your types, no?
- overgard 4y agoI think allowing people to call functions in a vast variety of ways is a mistake. It's one of the things that frustrates me the most about the javascript ecosystem, it's hard to figure out the call signature for any given function because there's like 15 different ways to call it. I'd argue it's better to just have one well documented way. It's not even like there aren't patterns for it, ie passing an "options" object or something like that (although even then I think that can be an antipattern unless there truly needs to be a variety of options -- ie a db connection or something. Better just to have multiple functions with specific purposes instead of one mega function that does everything)
- cogman10 4y agoAgree, 100%. Make your function definition `foo(foo: Foo)` not `foo<T extends comparable | int | Bar>(foo: T)` Flexibility is the enemy of a type system and library design in general.
- overgard 4y agoI don't think allowing users to call libraries in all manner of crazy ways is a good thing at all, and I don't think anyone would really be that put out by following a more pythonic approach of just allowing one way to do something.
- mmmpop 4y agoYeah but you're writing libraries in Javascript, that ship has sailed already. You're gonna just need a bit fat switch statement to check your input types on every public function you ever write.
- danielvaughn 4y agoCase in point, over the weekend I tried creating an npm package for a custom hook. Since it's public-facing, I wanted to use TS so I could expose types for users. Part of this hook is that users can pass in custom data. I tried to create a type that was basically "an object of any string key, with the type value". Gave up after like an hour of banging my head against my desk. Maybe I'm new to TS, but FFS it should not be that hard to do.
- jeremyjacob 4y agoFortunately that's not too difficult: let x: {[key: string]: Type} But maybe the documentation is lacking here?
- aylmao 4y agoFor the record, this is equivalent to: let x: Record<string, Type> Pun intended.
- deleted 4y ago[deleted]