26 ms·
JavaScript and TypeScript features of the last 3 years
- Killusions 4y agoI took the time to explain all the latest (and some older) JavaScript and TypeScript changes, including code examples.
- tobr 4y agoSymbols are not an ES2022 feature. I believe they were introduced in ES2015.
- Killusions 4y agoJust looked it up, you are of course correct. I will move them into the "Past" part.
- matthewmueller 4y agoThanks for doing this! I found this post very helpful to get exposed to recent changes from the last couple years.
- mook 4y agoLooked up on MDN (and from there the ES spec), import assertions don't seem to actually be standard. You might want to mark that somehow (or drop it).
- Killusions 4y agoYou are correct, I added a note.
- k__ 4y agoAre * and default the same?
- deleted 4y ago[deleted]
- shadowgovt 4y agoCan you clarify the question? In what sense are you asking if they're the same / not the same? In general, `import * from X` will pull every exported symbol of X into your current module at the top level (generally not recommended except for special cases like testing libraries; you shackle yourself to an assumption that the imported module won't ever add new symbols that might interact surprisingly with the importing module). `import * as Y from X` is slightly safer; it'll pull in all the exported symbols from X, but will wrap them in a Y namespace (so X's `foo` function is now `Y.foo`, etc.). `import {foo} from X` will just import the `foo` symbol from X and make it available in your module. Finally, `import foo from X` imports the single export in X that is tagged as default and names it `foo` in your module. (To my money, I don't like defaults very much. I much prefer `import {foo} from X` over `import foo from X` for clarity, even if `foo` is the only symbol X exports. It allows for future growth of X and avoids the unsightly `import foo, {bar} from X` that some modules end up growing in the future).
- FrontAid 4y agoNo. The former imports all the exports, and the latter imports the default export only. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#namespace_import https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#default_import https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- AprilArcus 4y ago`*` is the namespace object. `default` is a special named property on the namespace object. someModule.js: export default 'foo'; export const bar = 'bar'; namespaceImport.js: import * as SomeNamespace from './someModule.js'; console.assert(SomeNamespace.default === 'foo'); console.assert(SomeNamespace.bar === 'bar'); defaultImport.js: import foo from './someModule.js'; console.assert(foo === 'foo'); namedImports.js: import { default as foo, bar } from './someModule.js'; console.assert(foo === 'foo'); console.assert(bar === 'bar');
- qwerty456127 4y agoIs there a complete list of proper modern JavaScript features and examples covering all and only the features and styles which are modern (not neccesarily this new, perhaps some are 4-year-old) and relevantant + those which have never been replaced by any newer so are sill relevant although old but excluding outdated features and styles?
- Killusions 4y agoI haven't found one yet, but I'm sure there's one somewhere out there. I will try to keep updating this article so someday it will be what you're looking for.
- FrontAid 4y agoCan you make an example of features/styles that have been replaced? I'm not really sure what you mean by that.
- mordechai9000 4y agoAs an example, the immediately invoked function expression (IIFE) has been superseded by ES 6 modules.
- tofuahdude 4y agoThe classic example is .then .catch callbacks vs async await, though .then is still occasionally useful.
- qwerty456127 4y agoOthers have provided great examples of what I meant.
- schemescape 4y agoI’m not sure if this matches what you want, but I made a note of this site when I ran across it for a similar reason: https://javascript.info/ https://javascript.info/
- z3t4 4y ago
- dmix 4y agoIs it me or are Tagged templates a recipe for hard to read code? Just the way it extracts the substrings into arguments for unpredictable strings. It doesn't translate to readable code. I'd much rather use repetitive template strings. Unless I was doing some really fancy string manipulation. Or make my own functions with explicit arguments.
- deleted 4y ago[deleted]
- tobr 4y agoMatching up the template strings with the values is a little wonky because there’s always one more string than value. But it’s pretty rare that you’d write lots of different tagging functions, usually you write a generic one to use with many different types of templates. Tucking away complexity into a function to make nice and easy-to-use templates is a reasonable trade off I think.
- deleted 4y ago[deleted]
- renlo 4y agoThey've allowed "styled-components" to work though, which is pretty nice. I always thought of them as providing a way to parse DSLs directly in your code. For example, a fictional way to generate some config could look like this (using tagged templates): const thingies = ["a", "b"]; const config = yaml` - foo - bar - baz - thingies: ${thingies.map(thing => yaml`- thing: ${thing}`)} `; // config = ["foo", "bar", "baz", { "thingies": [{"thing": "a"}, {"thing": "b"}] }] At a company I worked at people were generating YAML using Jinja templates, but tagged templates to me would be a better approach. Is it hard to read? It can be, but compared to the alternatives it's not too bad.
- monkpit 4y agoconst thingies = ["a", "b"]; const thingToYaml = thing => yaml`- thing: ${thing}` const thingiesYaml = thingies.map(thingToYaml) const config = yaml` - foo - bar - baz - thingies: ${thingiesYaml} `; It doesn’t have to be hard to read
- transitivebs 4y agoWe need an equivalent "All AI breakthroughs in the last week explained"
- btown 4y agoTwo Minute Papers is a relatively good proxy for this! https://www.youtube.com/channel/UCbfYPyITQ-7l4upoX8nvctg https://www.youtube.com/channel/UCbfYPyITQ-7l4upoX8nvctg
- daavidhauser 4y agotoo bad i simply can’t stand the way he talks :( am i the only one?
- Cthulhu_ 4y agoProbably not, I dislike video / audio as a means to explain and update things, I'll watch the news (because the video adds to the story) but I'd rather have a text version if it's about software things.
- melling 4y agoSomething grating going on with him. I think it might be the way he tries to make it sound exciting for a general audience.
- jasode 4y ago>I think it might be the way he tries to make it sound exciting for a general audience. Looking at other videos of Károly Zsolnai-Fehér speaking at a podium to an audience, I think he's genuinely enthusiastic about the subject instead of putting on an act. However, when combining that unusual enthusiasm with a Hungarian accent, some listeners may find it odd sounding. Example vid: https://www.youtube.com/watch?v=-JdmOBA0WQ0&t=1m49s https://www.youtube.com/watch?v=-JdmOBA0WQ0&t=1m49s
- hungryforcodes 4y ago
- nickpeterson 4y agoNot to be the perpetual Luddite, but I hate how much programming languages change. I don’t particularly like go as a language (good board game though), but the minimal changes over time starts to feel really correct.
- bryanlarsen 4y agoThe changes aren't breaking. Javascript from the 90's still works.
- packetlost 4y agoC doesn't seem to have substantially changed in 20+ years.
- flohofwoe 4y agoThe C99 changes were pretty radical, but couldn't be broadly used until around 2016 when the Microsoft compiler finally caught up and started to implement the most important C99 features.
- kevin_thibedeau 4y agoC11 provides a lot of useful goodies too. I don't relish the idea of writing C89 and giving up all the improvements.
- RobotToaster 4y agoC23 adds support for type inference.
- kahrl 4y agoIt has.
- djtriptych 4y agoTo be fair, now that almost all professionally-written passes through a rewriting compiler, Javascript actually has evolved to a ecosystem that _can_ handle rapid (non-breaking) changes to a language spec. I'd also argue that the majority of these changes are to the standard library (new methods on String, Array, RegExp, etc). Not really core language changes. I don't know how often the go libs update but surely faster than the language spec?
- game_the0ry 4y agoAs a swe that works with typescript / javascript, I find this post exhausting. Am I the only one? Am I a shit swe? Edit - comments seem to suggest I was asking this question seriously. I was not, I was just (sort of) joking. That being said, front end engineering is rapidly changing all the time, so the confidence I have in knowing I will always have work to do (read that to mean: a job) is satisfying.
- __ryan__ 4y agoIt’s exhausting because: _____ If you find yourself struggling to articulate it, seriously and honestly consider whether you’re simply choosing to be stressed about it. I’m speaking from experience here.
- IshKebab 4y agoI don't think it's that bad but I wish they'd focus more on improving the terrible JS web API rather than adding language features. I mean they are adding features like static initialisation blocks when we only just got String.replaceAll(), and they somehow managed to fuck that API up despite it being explicitly a replacement for an existing bad API! Where are all the containers? Sorted sets/maps? Why can't I even map an iterator?
- HeavyFeather 4y ago> focus more on improving the terrible JS web API That's W3C’s job, not ECMA’s. > Where are all the containers? ? > Sorted sets/maps? Sets and Maps are sorted (by insertion order) > Why can't I even map an iterator? It's coming, but someone will likely be exhausted by that addition. https://github.com/tc39/proposal-iterator-helpers https://github.com/tc39/proposal-iterator-helpers
- IshKebab 4y ago> Sets and Maps are sorted (by insertion order) That's not what a "sorted set" is. C++ and Rust provide sets (and maps) that sort based on an arbitrary comparison operator. > ? ? > but someone will likely be exhausted by that addition I suppose. I guess it's one of those things that they really should have got right the first time. Like String.replaceAll(). I guess they will never add String.replaceAllSafe() - well just have to rely on linters to tell us that the API is terrible forever.
- Ezku 4y agoFrom the comments here, I was expecting to find myself hopelessly out of date, and to end up with a migraine trying to parse through a mindnumbing list of changes. Turned out I was mistaken. > Me: oh, cool, they fixed so many tiny things I had bumped up against > Some others: oh no, why are things changing I'm not getting it. Maybe I'm reading this wrong, but to me these seem pretty obvious small issues to smooth over.
- HeavyFeather 4y agoDevelopers love hating on JavaScript, on change, and on "complexification." This is all of the above. The first comment I read after yours is literally "I hate how much programming languages change"
- dayvid 4y agoThe big hurdle is a lot of new jargon that sounds more complicated than what it's doing.
- klodolph 4y agoAgreed. My main complaint is that some of these changes don’t filter down fast enough for my liking, because I’ve bumped into the issues they fix, often enough. That, and for various reasons, it’s easy to use "import" everywhere in browser-side code, but painful to use "import" in Node. That’s a major selling point for ESBuild in my mind—I can avoid dealing with Node as much.
- parentheses 4y agoThe way JS/TS change _feels_ a lot more haphazard. For example why introduce a new method to support negative indexing. Supporting `array[-1]` instead of `array.at(-1)` would mean one less thing to remember. Many of the changes make the language feel like a hodge podge made from parts of other languages. This lack of cohesion is IMO what makes upgrading the language always feel like moved cheese.
- connor4312 4y agoBecause your example is a breaking change, and breaking changes are hard to make in a runtime that needs to reasonably support two decades worth of web content. For example, if you have a `binarySearch` function that returns -1 if an element isn't found, a developer might do something. `const result = arr[index]; if (result !== undefined) { ... }`. This would then start returning the last element instead of undefined at that index.
- manv1 4y ago"The only programming languages that people don't hate on are the ones nobody uses." - someone online Negative indexes might actually be useful. At some point I actually need to read the actual language specs, I guess.
- manv1 4y agoFor reference, here's the current spec...all 833(!) pages of it. https://www.ecma-international.org/publications-and-standards/standards/ecma-262/ https://www.ecma-international.org/publications-and-standard...
- goatlover 4y agoThe author of C++, so maybe take that with a little grain of salt.
- calvinmorrison 4y agoC++: an octopus made by nailing extra legs onto a dog. — Steve Taylor But more seriously, languages that are less formally made and have grown organically all deal with these types of things. PHP is a great example of a language with a TERRIBLE core library filled with numerous "don't use this" and "yes this doesn't make sense" and esoteric foot guns. Of course, these languages are the ones that took off and people use everywhere. And languages like PHP have made great strides to the point that using PHP8 with a modern set of libraries is not so bad.
- goatlover 4y agoYes, but Go is also popular and famously resists doing that as much as possible. Maybe language popularity isn't a good metric, since there could be other reasons a language becomes popular. Worse is better, and what not.
- wiseowise 4y ago“Haha, C++ bad meme.”
- 4y ago
- synergy20 4y agoThere is another list with concise code samples https://www.javascripttutorial.net/es-next/ https://www.javascripttutorial.net/es-next/
- itslennysfault 4y agohmm... I've been using JS/TS for almost as long as they've existed. A lot of these are nice. Some less so. Some quick thoughts: - Tagged template strings. This just feels dirty to me. Probably won't use, but when I see it in a code base I won't be so confused at least - matchAll. I've never needed this. I've used match with g a bunch, but I never need the capture group. - Promise.allSettled. THIS is useful. I've implemented this (under a different name) in almost every code base I've worked on, and got bit HARD by not understanding this behavior long ago (huge production outage that took hours and many engineers to discover) - globalThis. EW. Don't think I have to elaborate - replaceAll. It's always annoyed me needing to use RegEx for simple replace all. so Yay! - ??=, &&=, ||= These seem really useful, but also potentially hard to read, but I think if I get used to their existence they'd become second nature - # private... not sure why they didn't just use the "private" keyword, but I don't care. I almost always use TypeScript anyways - static ... YAY! finally. Again, if they could do this i don't see why not "private" For the TypeScript stuff I'll just say the type system has kinda jumped the shark, but I don't hate it. It's SO robust and of all the new stuff being added I'll maybe use 1/10 of it, but it's good to know I can describe literally anything* with it if needed. * EXCEPT IF I WANT TO USE AN ENUM/TYPE AS A KEY IN AN DICT WHICH I REALLY WANT TO DO!!
- maxpowa 4y agoWRT Enum as key in object: enum TestEnum { Fizz = 0, Buzz, Bar, Baz } type EnumKeyedObject = Record<TestEnum, string>; type EnumKeyedObjectAlt = { [P in TestEnum]: string };
- t8sr 4y agoIf you asked me what the biggest areas were where JS needs work, it wouldn't be "syntax sugar for separating numeric literals", it would be stuff like "integers". At this point I'm almost afraid to ask, but if JS can evolve in major ways like this, why can't we address some of the basic shortcomings of the language?
- johnfn 4y agoIs BigInt not what you want? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- Killusions 4y agoIronically this is the only JavaScript change (except for top level await) I did not include, maybe I'll edit it and add it.
- pcthrowaway 4y agoThose are 2 of the most significant (and eagerly awaited) new(er) features though (although I thought BigInt was more like 5-6 years old) edit: Edge and Safari only added support in 2020, so it has only been useable without polyfills for a few years
- Killusions 4y agoI added them now so the article is complete.
- rwalle 4y agoI develop with JavaScript professionally and I rarely think about floating point number/integers when building UI or Node.js code. The "number" type is good enough in 99% of use cases. If you really need integers, there are specialized uint arrays and BigInt that handle various use cases.
- 4y ago
- temporallobe 4y agoFor me, the most awesome and useful change to Javascript has been the addition of private and static modifiers, although the implementation is kinda weird (why use “static” keyword but not “private” and the # sigil instead?). I use both TS and JS professionally but much prefer native JS and use it in my personal projects, however, the closer native JS can get to TS, the better, as I really do appreciate many of it’s features.
- kipple 4y agoThe # sigil has always bummed me out too. Supposedly it's because of this: > Why isn't access this.x? > Having a private field named x must not prevent there from being a public field named x, so accessing a private field can't just be a normal lookup. https://github.com/tc39/proposal-class-fields/blob/main/PRIVATE_SYNTAX_FAQ.md#why-isnt-access-thisx https://github.com/tc39/proposal-class-fields/blob/main/PRIV... Combined with this: > Why aren't declarations private x? > This sort of declaration is what other languages use (notably Java), and implies that access would be done with this.x. Assuming that isn't the case (see above), in JavaScript this would silently create or access a public field, rather than throwing an error. This is a major potential source of bugs or invisibly making public fields which were intended to be private. https://github.com/tc39/proposal-class-fields/blob/main/PRIVATE_SYNTAX_FAQ.md#why-arent-declarations-private-x https://github.com/tc39/proposal-class-fields/blob/main/PRIV... But I still think it's weird.
- illiarian 4y agoBecause they awkwardly bolted C++-like class syntax on top of prototype-based language and are now fighting that. Same goes for methods that you have to manually bind to `this` in the constructor etc. It literally is one of the "they didn't think if they should" parts of the language.
- temporallobe 4y agoThis is why I appreciate TypeScript, as it fixes a lot of Javascript’s syntactic goofiness, but of course I can’t use it natively, which takes it off the table for some projects.
- jakubmazanec 4y agoI love this thread, it has two of my favorite HN topics: 1) People shitting on JavaScript not realizing that their "obviously better" solution was considered and found not a good solution. 2) People shitting on TypeScript not realizing that conditional types and template literal types are awesome. I really like those type-safe routers (https://tanstack.com/router/v1/docs/guide/type-safety https://tanstack.com/router/v1/docs/guide/type-safety) and fully-typed database clients (https://www.edgedb.com/docs/clients/js/index#the-query-builder https://www.edgedb.com/docs/clients/js/index#the-query-build...).
- Waterluvian 4y agoTypescript is one of those things that makes me so productive that I have absolutely nothing to argue or prove. Their loss.
- RadiozRadioz 4y agoNot a rebuttal, just curious, how do you find your productivity compares to a "real" statically typed language (e.g. Go, Java, etc.)? Does your increase in productivity compared to JavaScript simply come from static typing, or is TypeScript itself the source?
- JenrHywy 4y agoIt's a bit of both for me. I'd say 90% of it is from simply having types; 10% is from some of the cool things you can do with TS types that aren't common in most statically typed languages.
- theonething 4y ago> cool things you can do with TS types that aren't common in most statically typed languages like what?
- eyelidlessness 4y ago
- jimmaswell 4y agoNot mentioned: importmap is supported in Firefox as of February. Also supported in Chrome and upcoming for Safari. Just in time as I finally started getting more into cutting edge JS with a personal project - job's been stuck on older JS for a long time and I haven't done personal projects in just as long. I've been running this project straight in the browser with no JS compiler. Are JS compilers going to be on the way out now?
- rwalle 4y agoImport map is an HTML feature and not in any JavaScript specification. JavaScript language does not care about how to find files.
- jenadine 4y ago> #private: […] This is not recommended for TypeScript projects, instead just use the existing private keyword. Why not? I was told the opposite: now that the feature is in JS natively, it can be used.
- conaclos 4y agoThe Deno style guide encourages the use of `#prop` over `private prop` [0]. Other guides such as the Google TypeScript Guide discourages their use [1] for now because they are transpiled to slow code. What I could conclude is: use `#` over `private` for runtimes that support them or projects that can target recent runtimes and browsers. [0] https://deno.land/manual@v1.29.3/references/contributing/style_guide#prefer--over-private https://deno.land/manual@v1.29.3/references/contributing/sty... [1] https://google.github.io/styleguide/tsguide.html#private-fields https://google.github.io/styleguide/tsguide.html#private-fie...
- bobbylarrybobby 4y agoProbably so that tsc can transpile it differently for older browsers.
- delaaxe 4y agoThere must be a mistake in the "Exact Optional Property Types" section?
- Killusions 4y agoHey, if you think you found a mistake, please also tell me what it is so I can fix it.
- Dylan16807 4y agoThe error message talks about having flags set wrong and doesn't complain about anything the code is doing. Also your code for "Tuple Optional Elements and Rest" is broken. Pad is declared twice and it's returning the wrong thing.
- Killusions 4y agoThanks, I fixed both of them.
- delaaxe 4y agoI think you mean to have undefined after the equal sign, otherwise I don’t see how there could be an error
- Killusions 4y agoYes, the error was also wrong, fixed it.
- delaaxe 4y agoI'd also assign undefined to 'age' to show that it's not erroring
- Killusions 4y agoGood point, done.
- panzi 4y agoObject.hasOwn(obj, name): Finally! That took long. Why would you even think that obj.hasOwnProperty(name) would be ok? If its unclear what properties there are you can't expect that the hasOwnProperty property to be working correctly. Always had to do the Object.prototype.hasOwnProperty.call(obj, name) dance.
- Andrex 4y ago> String.prototype.replaceAll 14-year old me hacking up my first JS on Freewebs.com is doing backflips right now. ...And 31-year old me is saying "What the fuck took them so long?"
- jankovicsandras 4y ago" Negative indexing (.at(-1)): When indexing an array or a string, at can be used to index from the end. It’s equivalent to arr[arr.length - 1) " sic arr[arr.length-1) This is wrong. Array.at can get, but not set the value. So they're not equivalent. console.log( arr[arr.length-1] ); // works arr[arr.length-1] = 1; // works console.log( arr.at(-1) ); // works arr.at(-1) = 1; // ReferenceError: Invalid left-hand side in assignment
- Killusions 4y agoThanks, I edited it to include this, just to make it clear.
- wellanyway 4y agolmao negative indexes in 2022