Lordy, I did not expect an internal refactoring PR to end up #1 on Hacker News. Let me provide some context, since a lot of people make a lot of assumptions whenever this stuff comes up!
If you're rabidly anti-TypeScript and think that us doing this vindicates your position, I'm about to disappoint you. If you're rabidly pro-TypeScript and think we're a bunch of luddite numpties, I'm about to disappoint you as well.
Firstly: we are not abandoning type safety or anything daft like that — we're just moving type declarations from .ts files to .js files with JSDoc annotations. As a user of Svelte, this won't affect your ability to use TypeScript with Svelte at all — functions exported from Svelte will still have all the same benefits of TypeScript that you're used to (typechecking, intellisense, inline documentation etc). Our commitment to TypeScript is stronger than ever (for an example of this, see https://svelte.dev/blog/zero-config-type-safety).
I _would_ say that this will result in no changes that are observable to users of the framework, but that's not quite true — it will result in smaller packages (no need to ship giant sourcemaps etc), and you'll be able to e.g. debug the framework by cmd-clicking on functions you import from `svelte` and its subpackages (instead of taking you to an unhelpful type declaration, it will take you to the actual source, which you'll be able to edit right inside `node_modules` to see changes happen). I expect this to lower the bar to contributing to the framework quite substantially, since you'll no longer need to a) figure out how to link the repo, b) run our build process in watch mode, and c) understand the mapping between source and dist code in order to see changes.
So this will ultimately benefit our users and contributors. But it will also benefit _us_, since we're often testing changes to the source code against sandbox projects, and this workflow is drastically nicer than dealing with build steps. We also eliminate an entire class of annoying papercuts that will be familiar to anyone who has worked with the uneven landscape of TypeScript tooling. The downside is that writing types in JSDoc isn't quite as nice as writing in TypeScript. It's a relatively small price to pay (though opinions on this do differ among the team - this is a regular source of lively debate).
We're doing this for practical reasons, not ideological ones — we've been building SvelteKit (as opposed to Svelte) this way for a long time and it's been miraculous for productivity.
I was skeptical at first when we made the change in SvelteKit. However, SvelteKit has a large integration test suite and being able to change the code and rerun the tests against the real final version of the code without waiting for any build step to complete has been a big improvement to productivity and I'm now a big fan of having made the change there. The tradeoff may be a bit different in Svelte core where we have more unit tests and fewer integration tests, so we're still investigating and considering the change, but we do have experience with both approaches and at the end of the day great software can be built using either approach.
I don't use Svelte, but I appreciate the principled approach and the clear explanation.
I primarily coded in Python for 4 years. Then I founded a company that didn't need as much data science and my primary language switched to JavaScript (2 years) then TypeScript (4 years). Overall, I really like TypeScript. But I do absolutely miss being able to cmd + click into a function/class from an open source package and see the actual implementation and not just a type definition. This is probably the biggest day-to-day frustration I have with TS compared to JS and Python.
What if TypeScript could compile to JS/JSDoc instead of source maps? I'm also not a fan of 'go to definition' bringing me to a dead end d.ts file, but also there has to be a better solution than verbosely JSDoc'ing all the things.
There was talk about introducing type syntax as valid but ignored in the JS language, making TS valid JS.
It would take forever to become mainstream but if node and major browsers started to support this tomorrow, along with ESM modules we could drop TS compilation and bundling entirely during development, safely publish npm packages as TS (even a bundled TS) and simplify tooling for monorepos, IDEs, etc.
Unfortunately that wouldn't solve dealing with templates like JSX/TSX or future language syntax/features.
Right yea that solution would be many years out and doesn't work for JSX. As opposed to compiling to JS/JSDoc which could be done today and should solve our problems with stepping into NPM package code without dead ends.
> Lordy, I did not expect an internal refactoring PR to end up #1 on Hacker News. Let me provide some context, since a lot of people make a lot of assumptions whenever this stuff comes up!
Because people want to follow in the footsteps of big projects that have gained specialized knowledge through experience.
It's also a really contrarian viewpoint about typescript which is really popular.
tbh, this seems pretty far out there. Sourcemap file size is a non-issue, they're not gigabytes, and editors like vscode now support going to the source definition for projects that support it. To completely switch over to js and then set types that way seems regressive. Just so that people can modify the source code directly a little bit easier? There are all kinds of tools ranging from ts-node-dev that make watching typescript files easy, with options to skip type checking for better speed. Honestly seems kind of backwards.
> It's also a really contrarian viewpoint about typescript which is really popular.
I really, really don't get the controversy here. JSDoc _is_ TypeScript, just with a syntax that's valid JavaScript (on account of it living in comments). This means it doesn't have to be built to run, but still gets all of the typing goodies regular TypeScript does. The end-user code authoring experience is the same or better.
> To completely switch over to js and then set types that way seems regressive.
"It's regressive to use a fully-JS TypeScript syntax instead of using dozens of tools on top of regular TypeScript to achieve the same outcome" is quite a spicy take.
> "It's regressive to use a fully-JS TypeScript syntax instead of using dozens of tools on top of regular TypeScript to achieve the same outcome" is quite a spicy take.
To be fair, "We are so invested in TypeScript we're dropping it!" is an equally astonishing take. It's language I'd expect from Google about any of their projects.
But that's the thing, it's _not astonishing_. It _would_ be astonishing if we were abandoning typing Svelte. We're not. We're not even abandoning TypeScript -- the whole project will still run `tsc` and enforce complete type-safety, it just won't use the compiled output. This is _abandoning one syntax for another_ because one syntax doesn't require a build step and a huge toolchain to run and debug.
This is surprisingly true in a way. TypeScript is not a language(1), it's primarily a linter-assisting overlay atop of an actual language, JavaScript. Also, there's a linter that outputs and bundles JS, shedding the alien type annotations and also injecting its own, very partial runtime.
So, JSDoc is just a linter/documenter aid. And so is TypeScript.
(1) TS is not a language: it has no spec, no reference documentation. It defines no behaviors, in particular, no runtime behaviors. It sits atop of various JS versions, layering over them in unspecified ways. TS is a linting layer, and also is a hack.
No.
At least, it didn't used to be. JSDoc had its own syntax, but now you can piggyback its format and put TypeScript inside. So now you can write `@type {Record<string, number>}` instead of the "classic" `@type {Object.<string, number>}`, and use some more TypeScript goodies.
You can even kind of use generics with JSDoc, still thanks to TypeScript, but then again... you're not really leaving TypeScript, you'll still have to deal with TS versions, and probably with some of the not-clearly-explained "papercuts" from above.
And finally, I'm not sure that JSDoc+TypeScript is perfectly equivalent to TypeScript. I have a hunch that some of the advanced strategies, e.g. involving `infer` or `extends`, aren't really replicable in JSDoc - or at least I have no clue how to do that in JSDoc - so we'll have to settle for weaker definitions in some cases. So, I'll have to see if it's actually "the same outcome".
I admit I'm no JSDoc guru, so maybe if somebody is compelled to try harder they might actually find a solution for a transition from TypeScript to a completely equivalent alternative. I'm all ears... but surely, if you try too hard the point will be lost.
All of this just to help the Svelte community to contribute - I'll have to take Rich' word for it. For now, it's the only community I've heard that switched from TypeScript in favor of JSDoc. They'll have to deal with a more verbose and less readable codebase for sure, I think there's no doubt about it. Is it really helping the contributors?
It may work for an open source project with a strong governance, maybe. I have a very different experience with projects that decided to use JS instead of TS. Unless we're talking about a very small project, it always turned out to be an ungodly mess.
> it doesn't have to be built to run
If this is a problem, then you have other problems...
Late to this party, wanted to add something here. Wholly agree with your perspective.
The counter-trend to this is the structural-first approach to TS, which eschews return types, and uses mechanisms like the 'satisfies' keyword to ensure that the type evaluates against known symbols, while maintaining the language-server inferred type product in all contexts. The tl;dr goal of this method is to make code that presses compiler-safety at every edge.†
Inversely, the JSDoc method sees you explicitly define everything, and what you save is writing a d.ts file (sometimes). You can pass the TS compiler over it, but it's not going to give you the incremental typing benefit. What you get are a bunch of black boxes with a published contract and a pretend-really-hard approach to typing.
That is frequently fine in cases like libraries. What I worry about is your average dev†† assuming this objectively traction-control-off approach to writing JavaScript approach is good, or rigorous. I don't doubt the svelte team is perfectly capable of writing code in this mode of delivery, and has an armada of tests to back up the proposition. The average dev always opts for easy, and therefore will take to this approach with gusto, but balk at the testing that is necessary to make up for some of the blackbox behavior (blind calls, function internal any, implicit unknown passing that TS would reject, et al) that may not be fully consistent with the behavior the purported type signatures suggest.
†for the sake of argument, I'll define "average dev" as people with a few years of experience still feeling out their place in the industry, and the 9-5 contingent who may or may not own a computer at home and like that paycheck.
††I don't necessarily rep this approach, it's just the other extreme*
It's not 1:1 in features though, but because you can import definitions https://www.typescriptlang.org/docs/handbook/jsdoc-supported... you can use a file a part whenever you encounter any of those advanced features / edge cases current JSDoc does not support.
Like other said, it's still TS after all, and there are escape hatches when needed.
In so many projects I use JSDoc TS, the amount of projects that ended up needing a manual .d.ts file not utomatically generated via `tsc` can be counted in half hand.
Maybe people could give it a try, after all if you comment a method, beside its signature and return types, you can as well just move types in there ;-)
That's an interesting hybrid approach, thanks Andrea.
Is this what Svelte will use? (Asking anybody that knows, of course.)
Anyway, to me the main problem in using TS with libraries is that we have 3-4 major releases per year, and they're just too many. Unless one takes a very restrained approach, releasing very generic (and thus less helpful) types that won't (presumably) break future (or past) versions of TypeScript, we need to release with `typesVersions` targetting n different versions of TypeScript. That's an ever-growing bother indeed for maintainers as time passes.
And I fear the hybrid approach above won't escape this issue. So using "pure" JSDoc or JSDoc with just a sprinkle of TypeScript actually makes sense... But I'd expect this workflow to be winning with smaller projects, and that's why this announcement for Svelte has been surprising to me.
> tbh, this seems pretty far out there. Sourcemap file size is a non-issue, they're not gigabytes
Sure, by themselves, but replicate that across everyone repeatedly downloading the library in various build processess, in various projects and with different versions.
Sure, by itself a sourcemap might not add up to much. But then there is various projects with different versions, who download the library repeatedly in different build steps. Then it starts to add up both in bandwidth, and in storage taken.
Luckily, there are still package and library maintainers who care about making things less, instead of more, both in architectures and size.
> Just so that people can modify the source code directly a little bit easier?
This is a real thing that is useful to think about, how to make your software easier to change in the future, while just solving the current concern without over-engineering the solution.
> Are we really talking about disk space in 2023? Seriously?
Well, it adds up, if you're doing multiple projects.
Doing a quick scan of my work desktop, I find 43,237 filenames matching ".js.map". The biggest is at ~10,000 KB, the smallest at 1KB. If we assume the average is just 200KB, in total they represent ~8.6 gigabytes (200 kilobytes 43237). That's not nothing.
> And bandwidth? Like we don't have several cache systems - including npm's - that can help?
Being conservative with bandwidth is a good thing for most. Not only will everything download faster because less is needed, but it'll probably be cheaper for you to run your application as serving less bandwidth either gives you a small bill if you use cloud, or requires less hardware if you're going the dedicated route.
Not to mention not everyone sits with the latest maxxed out Apple hardware for working, especially outside the SV bubble. These people deserve to be able to have a good development environment as well.
Overall, everything gets faster and cheaper if you save bandwidth.
> Ok, is there someone who can explain in details how would that help?
It's easy, the lesser moving parts your application has in the abstraction ladder, the safer and easier it gets to change things in the future.
Transpiling from one language to another to get a benefit you can also get by not transpiling a language from one to another, seems like a no-brainer to me in most cases.
I've been doing exactly the same thing for a number of years, and I find it a much more intuitive way to use TypeScript.
First, to ensure a focused discussion, I think it's a good idea to separate out TypeScript the transpiler, TypeScript the language, TypeScript the type-checker, and by extension, TypeScript 'types'.
Personally, I don't like transpilers. I never liked CoffeeScript and I hate not being able to see the 'actual' code when looking inside a Docker image in a K8s cluster. I also don't like using non-standard features in a language; I'd far rather live without something that is TS-specific, and if it turns out that this feature has legs, then just wait for it to be included in vanilla JS. (Not to mention that it smacks too much of vendor lock-in, for not much benefit.)
But I do get that this is to some extent because I'm primarily coding to Docker images, rather than multiple browsers. If I want to bump the version of Node to get some new feature, it's pretty easy. So I do recognise that for people working on the client side, where bundling and source maps and all that other chaos is the norm, then transpiliation is no big deal.
(Having said that, back in the day we all used to love that you could hack away on a web app using files on a file system, just loading HTML, JS, and CSS... It's a shame that we seem to have lost the 'vanilla first' approach to software, and leap to preprocessors for everything.)
Anyway... my first point is simply that TypeScript as a _transpiler_ doesn't have any appeal to me.
But I'm not about to throw the baby out with the bath water.
As with the original post, I love types! I think TS types are the best thing to happen in years. Where possible I like to use declaration files as the single source of truth (type first development). From there you can generate GraphQL and OpenAPI schemas, use them to drive contracts for implementation, share the files with other developers using other languages, and so on. And as with this post, I make the connection between the types in the declaration files and the code in the JS files, primarily through inference, and then as necessary through JSDoc.
As with many things, there is going to be a lot of personal preference to this. Since I like the way that Haskell puts type information on a separate line to the function that is being described, it's probably no surprise that I also find the JSDoc approach of putting the types in separately more intuitive.
And since it's easy to configure an editor/IDE to use TSC to lint and provide intellisense on JS files, you can get all of the advantages of TypeScript without having to transpile.
For anyone who is still confused - they're still gonna be using TypeScript in that they will have a tsconfig.json, `allowJS: true, checkJS: true` but they are just writing the files in JS with JSDoc type annotations, they'll still have `.d.ts` files to allow TS developers to use it without issues.
Is it contrarian - yes - is it insane - no, not really.
Edit: the motivation seems to be to simplify processes - running TS files can be awkward, and cross importing is awkward. fwiw created my own tool for this (https://github.com/tbjgolden/xnr)
> but they are just writing the files in JS with JSDoc type annotations
I think this is the critical piece not everyone understands. Under the covers, it's basically still Typescript (see https://www.typescriptlang.org/docs/handbook/intro-to-js-ts....). The major difference is that type information is specified in comments so that the source file is still valid JS and thus doesn't need a separate compilation step. There is not an exact parity between type info that can be specified with JSDoc and Typescript, but my understanding is that it's pretty close.
Any folks familiar with Flow (before Typescript essentially won out), Flow had something similar that was very nice, IMO better because it was the same Flow syntax, just wrapped in comments: https://flow.org/en/docs/types/comments/
I argue that it should support the other direction as well (.ts to .js with JSDoc instead of .ts to .js+.d.ts), but the TypeScript devs said they do not support that
It really doesn't look like that big of a change as well. Looking at the PR, they didn't go too heavy on their typescipt usage. I can see they when using typescript, they added types for function parameters, but not for return types, for example.
What is the reason behind choosing sucrase over swc?
FYI, you committed the wrong license file. The license file contains license text of a standard MIT License, but your project is licensed under Apache...
I know why it's fast (it doesn't do anything it doesn't need to), but not exactly sure why it's faster than esbuild-runner; presumably it had a higher latency when tested.
(and downsides not really, beyond it's pretty fresh so bug reports welcome)
We do this at my current company for all projects, it does not mean you don't use typescript, you will still validate all your files with TS, but there's no build step, just a check.
Very rarely we find a case that we can't cover with JSDoc annotations, and most of the time it means the code could be refactored to be simpler.
I do this now for all my personal projects, in my opinion it's simpler, faster and closer to pure JS.
This is great but -if I dare - wouldn't it be time to allow js to have type annotations [1] ? As in python, treat it as comments for now but with real syntax and let interesting dialects emerge from the consensus ? I like jsdoc but the syntax is urgh.
It will be impossibly exciting if that proposal happens. I hate build steps, one of the reasons I latched onto JS for my career, but TS is just so good that I had to go full blast with it after using it for the first time.
What your build/deployment steps without the Typescript syntax? Do you bundle or minify at all, or do you release your source files directly? Or is this mostly for NodeJS/server side stuff?
I ask because for most of my projects there's at least some bundling going on, and in that case the added complexity of Typescript compilation is pretty minimal - with tools like Vite there is no added complexity, because JS and TS files are going down exactly the same pipeline, parsed by the same parser, etc. And I could get rid of the bundler, which would make some things simpler, but makes imports and deployment more complicated. For the scale of projects that I'm working on, bundling feels like necessary complexity.
I guess I'm trying to figure out if this is a useful form of minimalism for the sorts of projects I work on, or if this is the sort of thing that works for some projects but not others.
It's really VERY easy to use something like esbuild or SWC though and just use TS for doing checks on the side. SWC would have ripped the TS annotations out of the top 100 TS projects on GitHub before I even finished typing this sentence.
I've been doing the same for years and I'm really happy with it.
But the one big annoyance is events - I've never found a satisfying way of writing a JSdoc that says what events a class emits, or what parameters the events have. Do you have a way of handling this?
Little side note, I'm always in awe of the amount of crap open source developers have to take from the community vs the crazy amount of value they offer. There's a lot of backlash on something 99% of commenters will never have to interact with. A lot of knee jerk reactions without trying to understand what's going on. And in return projects like Svelte offer an insane amount of value for people and businesses. Thankless work.
Nowadays it's expected that you get software for free, and if you don't like it you have the moral right to complain at insane lengths at the maintainers of this software. Even if you don't agree with certain decisions (which in this case shouldn't even be the case), there's a way of going about things, you're dealing with people, not faceless corporations.
Typescript migration was on our road map, but when we dug into it, it didn't solve the biggest issue we had with Javascript, which forces the developer to be aware of various pitfalls. Because of that, we didn't feel that TypeScript solved enough of JavaScript's faults to warrant a migration.
I still think that TypeScript is great and has some of the best tooling I've had the pleasure of working with, but in our case we didn't feel that the added complexity was worth the trade off. JSDoc is "good enough", even though we've run into bugs with it on VS Code.
The latest I ran into, `Object.keys(x).length` appears to recalculate length on every call. There doesn't appear to be a fast (and idiomatic) way to get top level object size in Javascript without using a secondary incrementor.
1. How on Earth would you expect a type validation library to assist with this example?
2. Looking at that example, I would expect that of course it would need to do work on every call. That is, Object.keys(x) is a function call that takes an object and returns a newly constructed array. So I'm not exactly sure what you would expect to be optimized here. I guess what you are saying is that there is no native `sizeof` operator for Objects, but this doesn't seem like some crazy decision.
I think the argument is that JSDoc already gives them type validation. If you're going to go the effort of porting to a completely different language and add a compilation step that new language better provide some benefits beyond types like papering over warts like Kotlin does.
I am honestly curious what issues you hit with JavaScript that you find difficult for developers to avoid. I do think JS has a lot of weirdness and pitfalls, but I feel like the things you are actually ever reasonably likely to hit are easy to enumerate and learn:
1. Understanding truthy/falsey
2. The difference between null and undefined (but this is an area where Typescript helps).
3. == vs ===, but this one feels pretty easy to avoid, e.g. just set up eslint to forbid == if so desired.
4. Understand the details of how JS treats 'this' in different contexts. I think this (pun intended) is probably the most important thing to understand.
5. The bizarreness that typeof null === 'object'.
There are of course other issues, but I honestly feel like I rarely if ever hit them, and I've been coding in JS/Node for many years now. I mean everyone loves to point out some of the insane implicit casting rules of JS (e.g. the JSFuck language), but I don't ever hit those in my day-to-day.
I just feel Typescript plus some strongly opinionated eslint rules take 99% of the "gotchas" out of JS.
If you've got enough keys that it matters you probably want to use a `Map` instead of an object? Maps are faster to write and read is approximately the same.
For those that didn't read the thread - this is for the Svelte compiler, not the Svelte library. Users of Svelte will be unaffected and typedefs will still be available.
Used to be really active in the svelte community and developed my own framework that got broad use. Getting Svelte and TS working together was a constant battle. This is a good decision.
Svelte will still provide type definitions. We're working on Svelte 4 currently and are taking the opportunity to make a few small breaking changes to the type definitions for improved TypeScript support: https://github.com/sveltejs/svelte/blob/version-4/CHANGELOG....
We'll cut a preview release soon and would love help testing and feedback from folks that have given it a try.
Type casting (type assertion, in TS parlance) is incredibly annoying to do in JS/JSDoc. In an ideal world, that would be a distinct advantage because type assertions are typically, or at least should be, considered risky: it’s a brute force way to ignore type errors. In the real world, you might find you have to correct inferred types, sometimes because they’re naively wide (eg, so many DOM interfaces devolve from HTMLElement to Element for no obvious reason!), but also often because they’re overly narrow (eg, so many dynamic collection member accesses completely ignore null safety, again for no obvious reason).
In practice, what I’ve found is that the hassle of adding type assertions even if they’re correct nudges me to write worse code (“to appease the type checker”) in JS/Doc than it does in TypeScript syntax. I don’t think TypeScript syntax makes me feel more relaxed about writing unsafe type assertions, but I’m probably an outlier because I pretty much only do that when I’ve exhausted every other available/known approach.
I don't care what svelte does, but I've maintained projects with jsdoc types and projects using ts directly and IMO using jsdoc tends to be more of a hassle to maintain, had worse ide guidance and in general felt just more cumbersome.
Being able to click through to the implementation in your ide is nice though, but can be solved by the ide.
If I remember right, symfony (php framework) has comments that affect how the code runs which as far as I’m concerned means they’re not comments at all but actually code masquerading as comments. Reading about JSDoc gives me the same uneasy feeling, even if it’s not quite the same thing.
Edit:
Here’s one example, you can define your routes in symfony using comments. Not only that, but it’s actually the officially recommended way of doing things. Absolute madness.
> as I’m concerned means they’re not comments at all
Smuggling pragmas in comment has a long and rich history. It’s literally the reason why json does not support comments.
> Reading about JSDoc gives me the same uneasy feeling, even if it’s not quite the same thing.
It’s not just “not quite the same thing”, it’s entirely unrelated in every way and shape. JSDoc does not affect the runtime behaviour of its code, or how that code interacts with other systems.
> JSDoc does not affect the runtime behaviour of its code, or how that code interacts with other systems.
At the moment. You’ve literally just said yourself that there is a long history of smuggling code into comments. A few years down the line I don’t want to suddenly have the feature added and then have to be on the look out when I’m debugging a codebase for secret code in comments.
There’s also a long history of smuggling code into JS comments (JSX pragmas, pure), and seemingly noop directives (“use strict”). They’re all hacky but there’s a very strong resistance in the community to mixing intent with JSDoc (good luck signaling anything to TS or eslint in a JSDoc block!). I think it’s safe to write this possibility off as “probably not inevitable”.
I don't see any comments there, I see attributes though [1]. Is that what you meant?
From the page you linked:
> Routes can be configured in YAML, XML, PHP or using attributes. All formats provide the same features and performance, so choose your favorite. Symfony recommends attributes because it's convenient to put the route and controller in the same place.
Attributes are not comments, they are an official structured way of handling metadata.
Attributes are a newish thing in Php that got created because people were using comments as code. And yeah, before attributes Symfony would use comments to define routes right above the function definition.
I’m sorry, but if it’s using the same starting symbol as a comment, and it’s greyed out in the text editor like a comment, then you can call it whatever you want, but it is a fucking comment. There are a bunch of unused symbol combinations on the keyboard that could have been used, there is absolutely no excuse for it.
> it’s using the same starting symbol as a comment
In Java the keywords "public" and "private" use the same starting symbol too, what's your point?
Attributes start with "#[", comments with "//" or "#". That's clear enough.
> it’s greyed out in the text editor like a comment
A language isn't responsible for a specific text editor's syntax highlighting.
Originally Symfony did use comments (docblock style ones like: /* @Route ... */) for this kind of thing, but since PHP 8 they've moved towards using attributes [1]. The syntax of the attributes #[Route(...)] might look like a comment, but they are actually just valid bits of code you can pragmatically inspect through reflection [2] and then choose to run if you want.
Docblock comments can also be inspected with reflection [3] but have a much looser syntax, so it was up to you to parse them. Where as you can create a new instance of an attribute directly from the reflection object [4]
In your example Symfony uses it to build up the list of HTTP routes by looking through all your controllers for #[Route] attributes. Generally that's done once and then cached, at least in production.
Personally I try to avoid using them, but they're definitely not comments. More like metadata you can attach to classes/methods/properties/parameters then use however you want.
> might look like a comment, but they are actually just valid bits of code
So comments that are code then.
Everyone can sit around going “This is not a pipe it’s a photo of a pipe or my perception of a photo of a pipe”. But if you did not have a sentence above your photo saying “This is not a pipe” or an arts teacher to tell you “this is not a pipe” and there was just a picture of a pipe on the page and someone pointed at it and said “can you tell me what that is?” You would say “why of course, it’s a pipe”. And then all of a sudden it started spouting water out of the end (let’s assume it was a GIF) then you can say “oh it looks like a pipe but it’s actually a water pistol masquerading as a pipe”. The fact that as a dev you have to constantly be on the look out for water pistols masquerading as pipes rather than having a clear distinction between pipes and water pistols is just a piss poor and easily avoidable design decision.
It doesn’t and I say in my comment that it is not the same thing. Nevertheless it gives me the same uneasy feeling because you don’t know what features are going to creep into the language further down the road.
JSDoc is like 20 years old and not part of the javascript langage, it’s just a way of formatting some comments such that they’re programmatically process able.
It seems extremley unlikely that Javascript would ever make comments affect the runtime of the language. I'm not sure why there's a fear here why browser vendors/es standards comittees would opt to go down this road?
JSDoc's PHP equivalent is phpDoc. It's just a way to document things and both are third party libraries that have industry-wide adoption.
What you're thinking of in PHP is not a comment. It's called an Attribute, is built into PHP itself, and while it does use a comment-syntax, it's the old style that is largely unused today ("#" at the start of a line). https://www.php.net/manual/en/language.attributes.overview.p...
JSDoc isn't similar at all, unless you build a compiler that does different things based on your JSDocs.
> Reading about JSDoc gives me the same uneasy feeling, even if it’s not quite the same thing
The key difference with TypeScript is that even "real" TypeScript types never ever affect runtime behavior, they are purely descriptive. This is an explicit goal of the project (and they've had to make some compromises in other areas to uphold it), so I don't see it ever changing
You can call it an “attribute” and you can also call it a “comment that affects the code” - they’re both just labels for the same thing. If you don’t want the latter to be a legitimate label (and it is, because I’ve communicated that idea with those words and you’ve understood what I’m referring to immediately) then the solution is to use any other symbol other than those reserved for comments. Imagine if we just had something like const a = 2 * 3 *[pineapples] * 10 and pineapples was coloured in like a variable in your syntax highlighting and people were like oh yeah don’t worry about that, that’s just a comment in the middle of the arithmetic. It’s ludicrous.
Is this all because it uses the hash symbol? I mean, you could probably call anything a "comment that affects code" if we want to get abstract. Attributes are in a bunch of languages, but they aren't comments. Comparing them to comments just feels like you're ignoring the fact that they are code that affects runtime.
I don't know the details of their situation, but I definitely can relate to the build step being a huge pain in the butt for Node projects. It's why I've stopped using Node whenever I can afford to, in favor of Deno (or maybe one day Bun). I used Deno to build a compiler for a personal language project recently, and it was an absolute delight not having to deal with any of Node's BS. Assuming they can't afford to migrate runtimes at this stage, I definitely get why they'd explore other options
This is a non-issue in practice — complex types can be expressed in .d.ts files and imported. SvelteKit (not Svelte) has been doing this for a long time and it's fine.
It’s usually a non issue for most normal use cases. Some exceptions are truly maddening though, if you have good reason to use them. One off the top of my head that personally peeved me enough to ragequit one of my side projects: you cannot, as far as I’m aware, define an interface and assign its type to a class (neither its static constructor nor its instance members), without redeclaring every single member type in JSDoc. You can’t (again as far as I’m aware) even define types adjacent to their project-local implementation module and treat them the same way as @types/typeRoots. Both of these would be solvable if you could <reference …/> without polluting global scope, but again that’s a behavior only (again as far as I’m aware) available to dependencies.
I’d be thrilled to make the concession to a TypeScript flavor of header/implementation file pairs and skip a build step for huge portions of my work. But I spent way too long trying to figure out how to do it and my only remaining hope that it’s even possible is to wait for the “you don’t know?!” replies. (If it’s not clear here, they’d be very very welcome!)
But I'm not a Svelte maintainer or user, so if this is their choice, I guess it is what it is. It's not something I'd ever consider. There are other approaches for making linked npm package workflows more manageable. There's the one mentioned by one of the VSCode maintainer, but the simplest setup is to just have a watch process running that recompiles on the fly.
We're using an automated tool to do the gross conversion, then combing through fixing the issues. There's a reason the PR's a draft, dammit! :lol: Don't worry, _no_ type-safety will be lost, internally or externally.
Maybe I am unfamiliar with jsdoc, or what the shape of Node from acorn is, but yeah if every function is returning any, that seems like a big downgrade and sacrifice.
It always makes me chuckle when a bunch of non-contributors come out of the woodwork to provide their opinion on a change which will affect them not at all.
I spend months trying to solicit feedback on new experimental stremaing/cancellation APIs in Node and it's silence for a year until people start using it.
We say that contributors agreed to list pronouns in the readme or we mention inclusivity and oh-boy do a lot of random people from the internet cares about how the volunteers that write the software they use for free refer to each other internally.
> oh-boy do a lot of random people from the internet cares about how the volunteers that write the software they use for free refer to each other internally
Oh boy. If they don't like it, then they don't have to contribute. (Spoiler: none of them are contributing anything.)
> As a Svelte compiler developer, debugging without a build step greatly simplifies compiler development. Previously, debugging was complicated by the fact that we had to debug using the build step.
In addition, using JSDoc does not affect compiler’s development safety because the type is almost equivalent to TS.
> Of course, Svelte developers (not compiler developers) will still be provided type definition files as now, so there will be no change for Svelte developers in terms of typing.
Someone who maintains the JS debugger for VS Code added this (in response to a Svelte developers saying they couldn't use a faster compiler due to debugging difficulty):
> It's an aside from the main PR, but I'm not entirely sure what you mean here. This should not exclude the ability to use alternative TS compilers--in fact, the js debugger itself is built with esbuild. The debugger should also handle runtime transpilers (like tsx) just fine.
I gave tsx a test and found it has a 3x slower boot than my favorite one, tsm[0] (and this is using the native binary at "./node_modules/bin/tsx").
Unfortunately, tsm has much lower download numbers compared to tsx, so I can already see me jumping ship to it due to traction.
I usually install tsm locally with "--save-dev" and use "node -r tsm --enable-source-maps <file>.ts" to run what I want. Here on a M1 Pro 32GB the difference between both is 0.17s for tsx and 0.06s for tsm.
I urge anyone that haven't tried yet to give tsm a chance. It works great with PM2 if you create a file like "server.pm2.js" and just add at the top of it "require('tsm')" followed by "require('server.ts')".
ts-node is responsible for my favourite error message in all of computing.
Yes better than: 'Error: success' or 'keyboard not found: press F1 to continue'
> ts-node: Unknown file extension: ts.
Someone will reply for a technical reason about this (mentioning .mts or package.json settings or whatever) but that doesn't change the fact that a program whose only job is to run ts files should know what a ts file is. GitHub issue: https://github.com/TypeStrong/ts-node/issues/1967
ts-node does not play well with ESM modules out of the box. I've started experimenting with tsx but it still has some edge cases of its own.
Honestly, ESM has been the bane of my existence this year as packages are slowly starting to migrate, and fixing issues lays on the developer, not any one framework.
with the difference that typescript generates the types automatically or at least tries to and in JSDoc the user needs to write the JSDoc.
Edit, btw:
Most complex types in the MR are now completly broken. It's crazy that there is a serious project out there who tries to mix jsdoc and typescript interfaces in the same project. it's like getting bad things from two worlds.
In general, your code is still valid JavaScript and can run in any browser or node environment.
Typescript probably is not going to disappear, but if it would, your code wouldn‘t have to change.
And you don’t loose your types, because the typescript compiler can interpret jsdoc as if you were using typescript directly.
10 years ago I have used Closure compiler from Google, https://github.com/google/closure-compiler/wiki/Annotating-T... , as a type checker. We had to use for production a different minimizer, not the closure compiler, but it was extremely useful to check for types and JSDoc-style annotations were very readable with minimal distraction.
Flow for JS from Facebook also supports types-as-comments, https://flow.org/en/docs/types/comments/ , but those are rather ugly as one has to intermix them with JS rather than using separated comment block on top.
yes this is much better. to be able to reach the actual source code which makes a function run is something we have all lost with so many layers in the middle.
The developers providing everyone with free tools are or course welcome to write those tools in whatever languages they want. But to me, the comment definitions are longer to type and more difficult to parse than inline type definitions. I would much rather use one of the quick TS compilers that don't actually type check when I want to make and test a small change to my source code. But to each their own!
If a person value- TypeScript's inline syntax so much that they disagree with the developers that build steps are a nuisance, then surely they can put in a build step for themselves—one that takes TypeScript syntax as input and then "compiles" it into the equivalent JSDoc so they're never forced to type out those long, long comments. (If this is disagreeable, then your position is a lot less consistent than you think.)
Finally things are heading in the right direction. Can't wait for more to do this. Typescript might be good for some, but I'm glad to see the hype finally begin to fade, so the rest of up can breathe again.
The biggest hurdle to using TypeScript is the build step before it can actually be run. If the type annotation TC39 [0] comes to pass this would be largely taken care of; _hype_ waxes. (unfortunately the proposal has been stagnant for more than a year now)
A lot of the new frontend codebases involve a build step before running. For such codebases, TypeScript's build hurdle has already been overcome.
Wow so much overhead, but I can see why if the problem is trying to step into some npm package code - landing on a type definition file is not helpful
It makes you think why can't the TS compiler produce JS code with JSDoc annotations instead of source maps. Ship the node packages with that so that debugging into the framework is seamless and easy to edit.
The business apps I work on don't benefit from SSR (having to write components that can render server-side is friction without payoff), and I already have a client-side router that supports nesting.
I'm still using https://github.com/TehShrike/abstract-state-router which I wrote years ago after thinking "ui-router is great, but I need a version that can keep using no matter what component library I want to use in the future"
Yes, because Kit won't work on my target platforms.
They've been focusing on SvelteKit, so plain Svelte has stayed pretty much the same for a while. It's nice, stable, feels finished. I'm ever so slightly afraid of what could happen now attention appears to be on it again.
The docs + tutorial are very good, even approaching "fun" (YMMV).
Yep, but slowly converting it all over to SvelteKit. Saves me having to maintain servers, watch setups, build processes, deployment processes, routing, bundling, and so on.
I love pure JS over TS any day, but isn't this using JSDoc in a way it's not meant to be used? Why would you use JSDoc as a JS type framework? Or is the post title a bit misleading...?
Because this way you get amazing IDE support with code navigation, refactoring, and (with strict mode) warnings about likely bugs and missing null checks.
I still feel vindicated, you don't need Typescript to write type definitions and also type safety on the server/api can be done with Graphql and writing gql
Wouldn't it be nice if all runtimes and browsers had native support for TS and you could just skip the entire transpiling and source mapping step? Oh, well.
I remember not using/trying Svelte because there was no TS support and it took quite some time before TS support emerged. With that in mind it doesn't surprise me they are not doubling down on TypeScript.
If you're rabidly anti-TypeScript and think that us doing this vindicates your position, I'm about to disappoint you. If you're rabidly pro-TypeScript and think we're a bunch of luddite numpties, I'm about to disappoint you as well.
Firstly: we are not abandoning type safety or anything daft like that — we're just moving type declarations from .ts files to .js files with JSDoc annotations. As a user of Svelte, this won't affect your ability to use TypeScript with Svelte at all — functions exported from Svelte will still have all the same benefits of TypeScript that you're used to (typechecking, intellisense, inline documentation etc). Our commitment to TypeScript is stronger than ever (for an example of this, see https://svelte.dev/blog/zero-config-type-safety).
I _would_ say that this will result in no changes that are observable to users of the framework, but that's not quite true — it will result in smaller packages (no need to ship giant sourcemaps etc), and you'll be able to e.g. debug the framework by cmd-clicking on functions you import from `svelte` and its subpackages (instead of taking you to an unhelpful type declaration, it will take you to the actual source, which you'll be able to edit right inside `node_modules` to see changes happen). I expect this to lower the bar to contributing to the framework quite substantially, since you'll no longer need to a) figure out how to link the repo, b) run our build process in watch mode, and c) understand the mapping between source and dist code in order to see changes.
So this will ultimately benefit our users and contributors. But it will also benefit _us_, since we're often testing changes to the source code against sandbox projects, and this workflow is drastically nicer than dealing with build steps. We also eliminate an entire class of annoying papercuts that will be familiar to anyone who has worked with the uneven landscape of TypeScript tooling. The downside is that writing types in JSDoc isn't quite as nice as writing in TypeScript. It's a relatively small price to pay (though opinions on this do differ among the team - this is a regular source of lively debate).
We're doing this for practical reasons, not ideological ones — we've been building SvelteKit (as opposed to Svelte) this way for a long time and it's been miraculous for productivity.