The switch(true) thing is a good example of something that is very janky that 99% of devs would never use. However, the fact that it did not work properly before and now does is still an objectively good thing. The language needs to be correct and this was a clear gap in the type narrowing system. Just because most people would intuitively go for if's does not invalidate the need to make this type of thing work properly. If I've learned anything is that just because I can't think of a use-case for something doesn't mean there isn't one. If the TS team decided to give this effort, I'm sure there was someone who had a very valid use case for it.
TS team are spending a lot of time shipping stuff that doesn't matter, I believe they need to work on the performance, I'm working on a codebase with 5k ts files and every time I'm trying to rename a symbol or use intellisense, it gets stuck forever. I'm pretty sure so many people having the same issue.
"That's the sound of bun having to support yet another thing" except this is already supported, its the bun import macro stuff you hated so much that you claimed change how JS does it they just implemented it before anyone else XD
Runtime support for `import type` in Bun/Deno/Node/browsers is not relevant. Type-only imports are a TypeScript-only concept that gets erased from the generated JS. So there's no need to talk about the effect of "resolution-mode" on Bun or any other runtime.
`import ... with ...` is a JS/ECMAScript feature already; TypeSript just added support for it (It was added to ECMAScript because import statements in vanilla JS already request the URL and interpret it as JS regardless of the file extension, so you couldn't do JSON imports at all. To add non-JS imports, they had to add new syntax to be backward-compatible with the existing JS import syntax. TS, on the other hand, can support both syntaxes, which makes the `with` syntax less useful in TS.)
About the instance field methods: there is (was?) indeed a usecase. In React Class Components you would write your event handlers (eg for onClick) as an instance field arrow function because of the issues with this. That way you always point to that field instead of creating a new function that captures this. Because of Function Components and hooks I haven’t used it for years. But as a memory optimization enthusiast you‘d probably like this more than useCallback.
Yeah, honestly, I think if you're not using inheritance (which I don't think I ever have in JS/TS), the semantics of closures assigned to fields are generally better and more intuitive. Using methods in callbacks is super weird, especially if the callback then gets assigned to a field of some class. If you do this.callback = something.method and then do this.callback(), the callback method will be called with "this" being the completely wrong object and type while it just works as expected with fields. You can use .bind() to fix it but it's not really great and easy to forget/unintuitive.
ok i get the appeal of inheritence & interfaces as a concept. but the example where the writer checks if the fn argument is an instance of a class which returns true only to get a run time error when invoking a method specifically defined in that class simply bc it implements an interface is terrible.
This why we can't have fast things. The runtime regenerates & reallocates those methods for each class instance. Instead of allocating a single class instance, you're allocated the class + N function instances. * Each of these functions is unique, yet, identical to all the others allocated in every other class instance. * The class size is bloated by + N unique pointer fields to those functions. * Since each method is unique, the runtime will never optimize or inline the methods. As far as it can tell, no two object, even though they have the same "Shape", have the same implementation. * The poor garbage collector... If your goal was to make it as slow and bloated as possible, about the only thing left you could still do is change the `Shape` midway through the objects lifecycle. Shape optimization was the only thing left the runtime could do, so if you want to kill that too: 1. Pick a field, ideally a non-null primitive that's referenced in a lot of places & assign an array to it. - Now pass your class "instance" to whatever static methods you have that aren't constantly regenerated (& may have actually stood a chance of getting optimized) to de-opt them all by blowing whatever assumptions the JIT may have made. - Bonus: If you suspect a function field by some miracle possibly got inlined, assign not a function to it, then trigger a code path that has up to this point only ever seen a function at that field offset. 2. If things are still too fast & that wasn't enough to de-optimize all the methods, force the object into hashtable mode by adding more fields to the object, then delete one the original fields. Ideally the first field so it'd have to shift everything down. If the runtime's fed up enough, it'll instead recreate it as a hashtable. - Pass your class instance (that's now a hashmap/table) to every method it was passed to in #1, ensuring whatever de-opt survivors there were earlier get what's coming to them for thinking they could be efficient.
Figured I'd be helpful now after my last comment. Ultimately in JS because of binding, generating function is unavoidable. But there's things you can do to minimize impact: 1. Declare the function outside of the class & in the constructor, do `this.field = (a, b, c)=> myfunc(this, a, b, c)` - This is by far most performant. Especially if you use exact arg counts (there is a slight hit if arg mismatch) - try to avoid referencing any variables besides `this` inside the call so only the class itself is captured. If not possible, in the class constructor do a `const captured = { this: this, other: myvar, .... }`, put everything you'll need inside it, & reference that same object for every other arrow function you assign in the constructor. 2. Put the function on the prototype and do a `this.function = this.function.bind(this)`. #1 is faster, but `bind` is prettier / less clever / more idiomatic. 3. Anytime there's a larger function or one that's called often and a candidate for inlining try to use the prototype whenever possible or functions that aren't unique/constantly generated such as static or module level functions. - Exceptions to this are functions that are immediately consumed at the callsite without leaking. For example: functions declared & passed inline to the likes of Array.map/filter, etc. 5+ years ago I went out of my way to ensure no arrow func was nested in a hot function or within a loop because of the garbage generated, but as of ~3 years ago it doesn't seem to matter. - The Cost is only paid if the function leaks out of the callsite scope, such as the case with setTimeout or an EventListener where it gets enqueued/put onto the heap somewhere. 4. Some function like setTimeout/setInterval take parameters, use them if you can.
it's crazy that lambdas close over this correctly in classes, but not in object literals because literals aren't scopes. it does make sense but it's so counterintuitive.
Please don't do this; it's such a waste of memory and garbage collector time. You're creating new versions of every function for every instance rather than just having one for all the instances.
@ThePrimeTime the only time 5:30 is acceptable is if you have cases that fall into each other and frankly even that is not as easy to read so the savings there are nil.
i guess the switch(true) stuff is for people who miss (cond () () ()... else) from Scheme? cond is alright but disguising chained ifs as pattern matching is horrible
I don’t understand why everyone thinks the ‘with’ keyword is the devil, but languages allowing implicit imports - like C# ‘using’ - that is almost the same thing but at a modular level. Both pollute the current namespace with another domain’s variables. This is the one important thing that Python does correctly, have explicit imports and discourage the use of the implicit import syntax when you only use a subset of what is available in a package. I feel that to create a language that is impossible to understand by reading the source code in a plain text editor, because you have no context where objects are coming from, is a poor design. Having the extra tools of an advanced editor/IDE shouldn’t give you the reasoning to ignore being able to read and understand code without having one.
Yes, JS is too slow for good tooling, but the appeal is that devs who primarily use JS can maintain and contribute to the tooling they use. Nothing wrong with learning a new language, but the mental shift is a barrier for a lot of people. This enables the users of a language to contribute to that language's ecosystem more easily, in a more comfortable way.
Every new version of ES/JS/TS just feels like they're heaping crap on top of more crap. Using a language with a real type system is just plain easier. The language itself is slow as molasses, but there's no reason the tooling has to be slow as well. Heck, Microsoft could rewrite TSC in C# and it would be a huge improvement.
Ive found across my career, that nearly every tool sucks? Why do I think this? Because everytime i pick up a new tool and begin to master it, i learn how much it sucks. I use TS/JS almost every day and I hate it. Ive never used rust outside of learning the syntax and i love it. Im sure if i started to use rust, id hate it
@@hamm8934 Yeah so very true. It's always a "grass is greener on the other side" kind of thing, since you learn to hate certain problems and see other languages fix them. As far as TS, I think it's a pretty good language and most of it's faults are due to it having to be built on top of JS, which is a god awful language, quite possibly one of the worst languages. As for JS... my personal most hated thing is NaN. It's considered type number, and NaN == NaN is actually false for some godawful reason. It's such an abomination of logic that it defies even the reflexive property of equality. And NaN does not count as a null result when using the ?? operator either.
@@taragnor thats a fair hatred. I hate both TS and JS’s lack of clear error handling the most. I think this is one of the reasons junior js devs get a bad rep. Every time we on board a junior js dev, they are utterly shocked in their first PR review at all of the feedback around needing to handle errors everywhere. Especially for self taught devs, ive never seen tutorials ever handle all of the errors that come about from async functions, promises, try catches, vanilla dom manipulation, calling a method on an object that hasnt init yet, etc..
@@hamm8934 Yeah the error handling is terrible. Really I can't blame programmers for not handling errors because in TS/JS it's not apparent what functions can even throw in the first place. TS lets you be a bit better about that, because you can create some union types using the TS type system to return either a value or an error, similar to Rust's Result type, and that union then forces the caller to deal with the potential of an error (or at least be aware of it). The problem though is that solution just works in your own code. All the JS libraries and internal functions that it's built on don't use that pattern, so you're still forced to interact with the godawful error system.
Hi @ThePrimeTimeagen, have you ever performed a profile on typescript? I'm wondering where the worst performing parts are, besides it being written in JS of course, and how feasible would it be to add in WASM components via Neon to speed it up. As a way to transition the codebase to Rust or Golang or Zig. Anyway, thanks for reading.
Once again the state of imports and package resolutions in this damn language leaves me scratching my head. Can this really not be simplified, AT ALL? It just gets more complex as time goes on.
I don't know if it translates to JS // TS land, but there was recently a video with C that showed there were some performance gains into the byte code with the switch statement instead of if/else. But being C it was only checking against one value, not multiple types. ru-vid.com/video/%D0%B2%D0%B8%D0%B4%D0%B5%D0%BE-fjUG_y5ZaL4.html
When you say "I don't know what this means", that is exactly what it is.. you don't know.. I cannot compare JsDoc to TS not because one is lacking, but just because "I don't know what it is" 🤷♂. Quoting Neil deGrasse Tyson, "when you don't know something, the conversation should end there". Finally.. I agree with you, there could be improvements 💯
the "is" keyword is to deal with the more FooBar side of strong types, it is there so we can make vaild good code that is type check without needing to add any the time. it is the ex. from C# with a Int16 can't be convert to a Int32? as Int32 is a sub type of the nullable ? type, and you need 5 lines of code to return a value because the complier need the Dev. help. a Type system is invalid if it need the dev. to do the complier job. so C,Cpp,C#,Java and Rust is all invalid languages that need to go back to the basement and fix stuff. OK.
ohh man... This whole video is Prime disliking stuff because he don't understand them, Please dude, there is real usecases for this stuff, if you need to hate on it, please try to use the feature first.
Ok, Im investing all my chips in Elixir now.. Tired of js/ts world and this version definitely didn't help! (if that doesn't pan out then I go to go/rust, but till then.. nah)
Prime Bun got the with for import in version 1.0, and you make fun of them for it, now lets kick them a little more for not having something they got.... perfect... the perfect i hate on any thing i know understand.
Never been happier since dropping TS and returning to native JS. Maybe simplicity is worth the single hour of debugging per year caused by type issues :)
i haven't written a class in javascript since react hooks was released -> they only added classes to the language to help people out who are forced to use javascript but demand OO style/thinking -> don't even use it; it's terrible and pointless
typescript used to be this cool thing to describe your JS types, now it's just a full blown mess after PMs got involved and decided to forego semantic versioning from 2->3 i think. Proof that literally everything gets worse when managers get involved.
JavaScript is the only language I don't want to learn or use. Visual Basic is probably a better language. But unfortunately the entire web is based on JS. We are screwed.
I don't hate javascript enough to ever mess with this crap. Holy hell, typescript looks absolutely awful. And those examples are some of the worst I've ever seen. Is it supposed to be some fun jokes, or just a showcase of the sad truth of typescript?
Write it in Rust then you can't run it in the browser without compiling to WASM or some crap. Clown takes living outside the context of the TypeScript project mission. But hey, it's a persona amirite?! What they are adding isn't crazy if you consider they are not building TypeScript for how you "should" write code, it's for how people "do" write code in JavaScript...