Comment by CharlieDigital
10 days ago
For the record, author is not crazy.
Svelte team also switched to JS with JSDoc a few months back[0].
You can see the majority of their repo is JS and not TS[1]
The cited reason[2]:
> 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.
There was a lot of noise when this happened. Rich Harris (Svelte team) even had a comment on this on HN[3]. Dev sphere similarly thought they were crazy. But Svelte seems fine and no one seems bothered by this now.
As long as author ships type def, it should behave just like a TypeScript library for all intents and purposes.
From the link [3] you posted,
> If you're rabidly anti-TypeScript and think that us doing this vindicates your position, I'm about to disappoint you.
Rich and the rest of the Svelte team are still using typscript, just through JSDoc + type definition files.
In contrast the Nue team seems to want to keep the view layer untyped.
From the parent comment
> real static typing (like Rust or Go) shines in business logic where it counts
it seems they don't consider typescript to be "real" static typing.
TypeScript is not "real" static typing in the same sense as Go, Rust, C#; the type information disappears the moment you build it.
Will happily accept:
At runtime (and thus the need for schema validators like Zod, Valibot, et al because dev-land "static typing" is a façade)
To be clear, they are not "using" TypeScript, it's more accurate to say they are providing TypeScript bindings.
Their codebase (as in the actual code they are writing) is undoubtedly JS[0] with `.d.ts` bindings for TypeScript[1]. Author can also do the same and provide TS bindings at any point in the future.
[0] https://github.com/sveltejs/svelte/blob/main/packages/svelte...
[1] https://github.com/sveltejs/svelte/blob/main/packages/svelte...
And this is definitely a problem.
Had I had the opportunity to choose a language across the entire stack with mature wide adopted frameworks and libraries, I had done it.
Had there been something line Rust, Go, Java, C#, etc. that would work end to end, that would have been amazing.
In practice, even the weak safety typescript provides catches so many bugs before they hit production that it is indeed worth it - I have more than 140k LOCs of Typescript in production, and that would not be manageable without types.
8 replies →
> To be clear, they are not "using" TypeScript, it's more accurate to say they are providing TypeScript bindings.
Interesting that you say it's more about providing "bindings", and not really "using". Much of the types in the svelte codebase are never exported outside of svelte, and they are only consumed internally.
The problem they were having was with transpilation, since the browser doesn't run JS.
From Rich Harris (months after svelte switched to JSDoc) [1]:
> removing types from your own code is clownish, epically misguided behaviour, but whatever — to each their own
I would suggest going through the issues and PRs in the codebase to see how invested the Svelte team is in typescript.
> TypeScript is not "real" static typing in the same sense as Go, Rust, C#.
That is true for Go, Rust, C#. But the same thing is also true for languages like C, and Generics in Java. I'm sure both of those languages have weak type systems, but are definitely statically typed.
I think the fact that type information is lost after being compiled isn't really a classifier for typed/non-typed. Ultimately it all comes down to machine code, and that certainly isn't typed either.
[1]: https://x.com/Rich_Harris/status/1699490194565578882
Does Go’s type system perform runtime type validations? My impression was that it does not. But Go probably supports reflection on the type information at runtime which could be used to implement a runtime type validator, right?
You can write a function in go or rust, then write code in assembly to call it with any old nonsense. It is no different. The whole point of static typing is that it happens at compile time, not runtime.
> TypeScript is not "real" static typing in the same sense as Go, Rust, C#; the type information disappears the moment you build it.
The type information in both Rust and Go disappears the moment you build it. The generated assembly is completely untyped: if you pass invalid objects to a compiled Rust function that you've dynamically loaded, you will cause problems, even memory safety issues, because Rust does not do any type checks at runtime.
In the same way, if you call Typescript-defined functions from Javascript with the wrong types, you'll get problems. But if you write everything in Javascript, and don't ever use type assertions, you won't have issues. (In practice, I believe there are a couple of other issues you can run into, typically involving variance and mutability, but these are very rare. Also, some older APIs return `any` that should return `unknown`, but that can be fixed.)
It's also worth keeping in mind that all languages have and require schema validation, it just might look different. Both Rust and Go have schema validation libraries - typically they parse the data directly into the correct format, but in Rust you could do something like `let x: HashMap<String, JsonValue> = string.parse()` and get roughly the same effect as Javascript's JSON.parse, it's just that JS/TS has a built-in data structure to represent arbitrary JSON data, whereas Rust does not.
> To be clear, they are not "using" TypeScript, it's more accurate to say they are providing TypeScript bindings.
To be clearer: they are absolutely using Typescript. The functions (and other parts of the code) are annotated using Typescript's extension of JSDoc types, which means Typescript can parse and typecheck this code as if it were "normal" Typescript, including generating type definition files. The .d.ts files in the source code are used to define additional types and interfaces that can be used in the .js files (you can see the first file you linked to import type definitions from ESTree, for example). The type checking step can be seen in the package.json file[0]. This is all explained in the comment from Rich Harris that you linked before.
Using JSDoc rather than conventional Typescript syntax makes writing your source code more complicated, but in this case the Svelte team figured it would benefit them more in the long run to still be writing code that could be interpreted by a normal Javascript runtime. However, it really is just a different syntax for Typescript, and that's how they are using it.
[0]: https://github.com/sveltejs/svelte/blob/80557bbc1c8a94c43a95...
It’s not real static typing. A compiled typescript project is just javascript, which will still gladly accept incorrect types. The types only matter during compilation.
This is the real-est static typing that exists. "Static" refers to build time. By definition static types are checked at build time, not run time. If you want types to be checked at run time, that's called "dynamic" typing.
4 replies →
> The types only matter during compilation.
That's pretty much the definition of static typing.
You're confusing "real static typing" with runtime type information. TypeScript has "real static typing" (if you disagree, ponder for a moment the meaning of "static"). A TypeScript program cannot natively query the _TypeScript type_ (not to be confused with the corresponding JavaScript type) of one of its variables in the way, for example, Go can. But neither can C, or C++, or Rust, all of which are unquestioningly statically typed.
Svelte is a bad example. They have roughly identical type checking before and after that switch. The switch is mostly just an aesthetic preference for one syntax over another and an ideological stance about being able to run code directly in a browser without a build step.
It's not an "aesthetic preference"; it's a functional preference for debugging and iteration speed as cited by the team.
Fair enough. Perhaps what I mean is that they don’t have a strong aesthetic opposition to JSDoc, which is presumably rare among TypeScript developers.
This is why I prefer to stick with JS and JSDoc.
I have been doing pro webdev since 1995 and since I got my initial experience without all of the contemporary tooling, my process has evolved to require very rapid iteration: the delay of a compile step can often break my concentration and prevent a flow state.
https://news.ycombinator.com/item?id=43548647
Which is quite hypocritical coming from a compiling framework and thus such a ridiculous stance.
We hate build steps in our build step.
> Svelte team also switched to JS with JSDoc a few months back
1. They still use types via JS Doc
2. They only switched to that for their internal development
3. User-facing code has all the type support and TS support you'd expect
> Rich Harris (Svelte team) even had a comment on this on HN[3].
And here's literally what he said:
--- start quote ---
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
--- end quote ---
Compare that to Nue's author's take
Svelte uses JSDoc and has TS validate that. Nue uses nothing. This analogy makes no sense.
Svelte still exposes types though, right? Like as a svelte user, you wouldn’t know it was written in JS?
I don’t use svelte, that’s just my understanding from when the TS -> JS switch was announced
JS with JSDoc is basically just awkward Typescript.
You're speaking as though it is a fact, but I think it depends on your coding style and temperament for iteration delays.