← Back to context

Comment by unchar1

10 days ago

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.

    function fn(x: string) {}

Will happily accept:

    fn(2)

At runtime (and thus the need for schema validators like Zod, Valibot, et al because dev-land "static typing" is a façade)

    > Rich and the rest of the Svelte team are still using typscript

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.

    •     >  I have more than 140k LOCs of Typescript in production, and that would not be manageable without types
      

      The Svelte team achieved it with JSDoc. Google's JS style guide also focuses on JSDoc for the same reasons[0].

      And to be just a tad pedantic: you have JS in production; your TS is only in dev.

          > Go, Java, C#, etc. that would work end to end, that would have been amazing.
      

      It's not that you can't; it's that you choose not to (and yes, generally for good and valid reasons). There are end-to-end solutions for C# (e.g. Blazor), for example, that are perfectly fine depending on your use case (not great for all use cases). Fable is another example using F#[1]

      There are also libraries like Bootsharp[2] that are doing interesting things, IMO, and has some of the same energy as OP's project (moving the typing and logic into a runtime that supports runtime static types and interfacing minimally with JS)

      [0] https://google.github.io/styleguide/jsguide.html#jsdoc

      [1] https://fable.io/docs/

      [2] https://sharp.elringus.com/

      7 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.

    • Sure, you're technically correct. But TS is compiled in to JS, which is dynamically typed at runtime. You're still ultimately in a dynamically typed language.

      In addition, in a typical statically typed, compiled language, your only place where you interact with data that isn't guaranteed to be type-conformant is at a foreign function interface, whereas in Typescript all your interaction with third-party libraries is via regular JS and may or may not be type conformant.

      3 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.