Design Doc: Use JavaScript instead of TypeScript for internal Deno Code
docs.google.com
docs.google.com
I will say I don’t quite feel as strongly about CSS pre-processors like SCSS, which I really enjoy, however I still prefer plain old CSS for the same basic reasons.
The type war was "won" by TypeScript, and I expect it's just a matter of time before types make it into the standard. The benefit of winning so completely and having such enormous popularity is that its ideas are very likely to make it into the standard such that no transpilation will be necessary.
I hope so too. TypeScript has done so many things right in its design and implementation - starting from Anders Hejlsberg, with expertise in creating numerous languages; backward compatibility to allow gradual and seamless migration from JS to TS; structural typing; editor/IDE integration via language server; good documentation; corporate backing (maybe not necessary, but like React, I think it was a big factor in its wide adoption).
so in 2016 typescript was around for 4 years, and here we are now 4 years later. its still around. seems to be holding.
https://en.wikipedia.org/wiki/Lindy_effect
Transpilers definitely aren't Lindy. CoffeeScript, GWT, Elm, among others form a huge graveyard of de facto defunct languages targeting JS.
It's an unhappy situation for all involved really. JS should be a language that targets some kind of bytecode that the browser executes rather than being a direct target.
Perhaps WASM will some day replace all webpage scripting allowing everyone to use languages of their choice.
How do you suggest addressing this in a 10 dev team when developing in js?
It's much worse than just using TypeScript (only at runtime, PropTypes aren't that useful anywhere else, PropType syntax doesn't match Flow, TS, or jsdoc, ESLint can't check any PropTypes you spread in), but it can get you by in a pinch.
Hit me up in the e-mail in my profile if you want to discuss this further, would be happy to help and discuss my reasoning further. I've been doing a LOT of TS code recently on all the major target platforms for React - browser, electron, and react-native. I manage a team who's built several applications now and we use TS for everything, including an automatically-generated TS api interface that exposes types from our C# REST backend using swagger directly to the client code.
You can leverage ocaml/ml as well as js ecosystem. Mix different files and syntax.
Bsb is also faster than tsc.
- non-standard ordering of arguments between belt/standard library
- Ocaml's standard library actually generally avoiding the Option/Result type, in preference of exceptions, which is unexpected and a pain since it's an ML.
- package management involves manually adding things to the bsconfig (has this changed?)
- things randomly break between relatively minor Bucklescript versions, they broke something pretty important in like a .x release when I was messing around with it
- server side isn't good. It technically works but all the bindings are old or terribly documented, and you never really know if it's not going to blow up at some point.
Otherwise, I actually quite like it! None of those are actual core language complaints.
I had some negative experiences with typescript in a large React project but in that case the most negative experience was that often the type definitions provided by React and common type libraries didn't match our needs, which made doing something that would normally be quick difficult and long.
The reason for types not matching was often that we needed to generate HTML emails as part of things, which means you need a lot of deprecated attributes, so probably you won't have this problem.
For example I contributed to Typescript's definitely typed project in the past. To make typescript more useful. But I ended up spending so much time writing type definitions. After all, I rather have some NaN or "undefined is not a function" exceptions during development.
I like letting my tools do stuff for me. If a tool can go look up what arguments this function expects, and their types, and tell me that, rather than my having to go check, and then also warn me if I typo one of them, then also take me straight to the definition of the function if I decide I want to read it, without my having to go hunt it down manually, all at zero cost (again, these things should be documented anyway), then why the hell not?
[EDIT] I guess I just don't understand why people consider it burdensome. You probably ought to know your function's going to take a string. Is it that hard to type "string" in the signature? You're gonna have to figure out what it's supposed to return—when you do, write it down. It's a little more work for more complex structures but it still amounts to typing out things you already have to think through anyway, and the more complex the more important it'd be to record that somewhere, so may as well be machine-readable type information. In return, when you accidentally try to treat your string like a number you'll immediately know you've missed a step, you'll get comprehensive autocomplete on hashes and classes and such, jump-to-definition, instant typo-spotting, automatic refactoring, and so on, and you can hand it over to someone else and they'll get those same things, instantly. The payoff is 10x, at least.
That said, in proper type safe development at least your own API comms should be type safe. It's easy if you use the same language on client and backend, which is possible with Typescript, Reason/Ocaml, Scala, Rust, etc.
The problem with Typescript is that it's half assing type safety in the language itself and people generally half ass type safety in other aspects of development too. You just can't expect to reap the benefits of real type safety with such an approach.
Also I don't think the transpiler argument holds in today's JS ecosystem. Everything is transpiled. Unless you are developing in barebone ES5 syntax and avoid babel as a whole, then some level of transpliation is inevitable. Yet, I didn't find debugging that much difficult with correct setup.
ES6/2015, sure; ES2021, though...
For the latest useful JS features, you need a compiler, whether it's TypeScript or Babel or...
I think that'd be super cool.
Modern static ESModule JS is quite good. I have several projects north of 30KSLOC written in modern JS. I'm not living in "undefined hell" because I use named-export ESModules, I check types all over, and I write quality tests. A little discipline goes a long way.
Which is something you rarely need to spend time on if you're using TypeScript.
[1]: https://www.typescriptlang.org/docs/handbook/jsdoc-supported...
Also, I've been doing web dev for 25+ years now and I don't like the trend backward to waiting for code to "compile".
Although if you're going to have to compile, Svelte looks like a nice middle-ground.
If your comment were code, TypeScript would have caught your typo at compile time, versus JavaScript where your users would have experienced this (potentially catastrophic) error at runtime.
This is the main value we get out of TS. If we rename a property on a viewmodel, we then update a TS file containing all the models. In this trivial example an auto refactor might propagate the change, but if it didn’t we get type errors all over the application telling us to change this. In JS, there’s an overwhelming possibility we miss one of these, and it isn’t picked up until production.
Real-life example: I recently came across some code that checked for a rare error. It was in the form,
if (object.property === CONST_ERR_CODE) { /* handle it */ }
At some point, `object` had been refactored and `property` was no longer on it, effectively turning the statement into "if (false)".This class of issue is probably my least favorite thing about js at any type of scale. It's so incredibly permissive that even simple tweaks need to be scrutinized carefully, whether by human eyes or unit tests. Using human eyes means I can't write js when I'm tired at the end of the day (otherwise the perfect time for small, no-functional-changes refactoring), and unit tests for trite details are boring -- I'd rather spend that effort up front, to appease the compiler.
On the other hand, js is incredibly nice for prototyping, before I have to care about edge cases.
Non platform languages introduce those extra layers, while bringing along their own FFI issues, idiomatic libraries and other set of issues to care about.
I only use TypeScript alongside Angular, as one could somehow consider Angular to be the platform, for anything else Web related, pure JavaScript with script tags (yes I don't bother with JavaScript transpilers either).
If you're using ESLint, I'm quite sure you'd like TS as well, so if that is the case, you might want to give it an actual chance.
Their point seem to be that no matter what language you prefer to be compiled to JS, in ends up being JS anyway so you might as well write JS directly, because of the reasons provided in the last post. I don't agree with them (ClojureScript is the language of choice for me), but you're not arguing with good faith here.
That being said, the commenter above them could've also been referring to old old JavaScript where no transpilation is needed to reach practically every target environment.
It seemed to me that the author was describing the (somewhat common?) practice of writing client code directly in ES5 and perhaps polyfilling any missing features for any targeted browsers that required specific fills.
I, personally, find ES6 to be ugly and requires me to pretend all sorts of things that are not true for the targeted runtime. It's like a whole fake world, so I'll prefer to avoid it unless there's some obvious reason to use it, as in an existing front-end build toolchain and a spec to use ES6, etc. Greenfield? I guess Svelte and such will use it, but if Typescripting, then one will just write Typescript, right?
What runtime are you using that you can't run ES6/2015 natively in the console?
I will be happy when I leave wart-land, but only when I really leave wart-land, not when it's just "lipstick on the wart"-land.
Types and classes sound nice, but only if they really exist, and not as mere compiler advice. A type is really a memory shape/size/structure in compiled languages.
Ok, having said all of this heretical nonsense...
(and yes, I've used React, Vue, etc. I tend to like Mithril best, and avoid JSX as I've no problem with hyperscript, and have even made my own lousy reactive hyperscript that I don't use (lol) in favor of Mithril)
... i DO have to say that Typescript seems like a nice/useful tool for teams, were transpiling to be accepted for the project needs, after weighing the costs/needs. I am recently rather fascinated by Svelte, and I'm mostly trying to break things and see what generated code looks like, etc. I'll admit that ES3 get's a bit useless, hence the polyfill. Minified JS with single-letter variables is usually a hoot to read.
You solve scripting language problem with better code organization? While in the first place the language was designed to solve scripting problems, DOM manipulations, now you can use JavaScript to build backends and SPA's hybrid apps, and most importantly some huge code base of libraries like Gatsby, vscode, where large teams are collaborating in the same project. How would you solve all the runtime errors? How would you solve expending the capability of your code editor? How would you solve refactoring? Just to name very few of what something like Typescript is capable of.
It sounds like they are discussing the central code runner of deno. I would have expected this to be compiled to JS in any case, but it seems like they are compiling the runner, then compiling user code. Of course that's slow. It's also not representative of a normal TS use case, which is unfortunate because I expect we'll see this discussion shared all over the web as an argument for dropping TS.
b) There is a valid, broader point to be made here that while TypeScript itself doesn't carry any runtime overhead (by design), it can in some cases force you to contort your code, so that it can be type-verified, in ways that have a runtime impact. In my experience (a couple of years writing TypeScript professionally) this is uncommon and not a huge problem, but does happen occasionally. It's also worth noting that the vast majority of these cases can be papered-over using //@ts-ignore, "as" casting, etc. if necessary.
I don’t use classes or inheritance in my own code and it’s incredibly liberating. The result is data structures and interfaces that are primitive and independent, which removes so much fragility.
Meanwhile, people would be on my ass trying to understand why I can't just simply hook up that decent looking prototype to API and release it.
[0] https://github.com/denoland/deno/issues/5432 [1] https://github.com/swc-project/swc
I'm not really sure what this post is getting at. I trust Ry knows the issue better, but from what I've read I have the same questions as everyone else here:
- Why is Deno defining interfaces and classes like that?
- Will this mean losing type checking in projects using deno?
- Why not strip types in development and only check at commit/push/build times?
EDIT: Sucrase! That’s what I was thinking of:
They do consider swc (which has roughly the game goal as Sucrase) in the conversation, so it seems like there's some consideration of a transpile-only approach. TypeScript's built-in `transpileModule` is probably the most reliable and officially-supported way to get the equivalent, and is much faster than running TSC with typechecking.
Or would the Typescript internals not have been available in that way anyway? It just seems hard to compete on ease of use with Node in VSCode without whatever magic is making the editor so smart - which I assume is something to do with Typescript.
In this case it would be even easier since it's already in Typescript and would presumably be a straight port, so all of those type definitions can be automatically generated from the existing code and will just work.
> ry So - to make a long story short - we're removing the types from internal code and making it pure JS this reduces complexity and helps us ship a faster product. I acknowledge it's unfortunate to lose the type information, but it's really masking larger problems. It's not going to happen immediately tho. We have a bit more work to figure out how exactly it should be done. It's not going to be one big 9000 line file either. But it might not be ES modules. depending on if we can make that work or not.
The “lose the type information” there suggested to me that they’re not planning to ship them at all.
It's like them running the TypeScript compiler to generate one large JS file and using that intermediate as what people build against instead of the original TypeScript source. I'm not sure if this is what they're actually doing (or if they're somewhat manually doing the equivalent of it), but as a hopefully short-term workaround that allows them to solve the problems, that doesn't seem too bad (but it does possibly highlight some TypeScript problems).
Even if they actually move to a large core JS file that is the active development target, as long as they keep track of the TypeScript specifics (and don't code themselves into a corner assuming something works that they find much later errors), it may not necessarily be hard to go back to TypeScript from that (possibly with a lot of it automated with a lot of structured comments).
To me this reads more like a list of issues in the deno architecture, and how they integrated TypeScript, than any issue with TypeScript itself.
I know the JS engine is V8 (C++), and the rest is Rust and TypeScript, but which parts are Rust, which parts TypeScript? Why 2 languages? Is it mostly Rust, mostly TypeScript, or a bit of both?
Also, what are the hardest problems that Deno solves internally? Like if you’re working on Deno, are you mostly working on ... the dependency resolution/package management? Automatic compilation of user TypeScript code? The standard library? Something else entirely?
He had a great talk [2] about the lessons he learned when creating/maintaining NodeJS. Many of these lessons are being applied to Deno.
Here, as far as I can tell, "Deno code" specifically related to the code shipped to the developer / user using Deno, the compiler / runtime.
de no
no de
node
heh.
Shocking
In response to your personal experience, I'll share my own: I switched from C++ to Java, to .net, to Node.js, to Typescript. Working on Node/TS I have never been on a team that wastes so much time fixing silly problems that a better language would simply not allow to happen in the first place. I have also never worked on a team that spends so much time dealing with issues in poorly written community packages, or arguing with package maintainers who could never in a million years pass a technical skills test at the company I work for.
Deno is, by definition, not Node.js. Typescript can live outside of Node (like when it's compiled for and runs in the browser). So I think you're getting downvotes because it reads like a generic rant about the same things we've already heard about in a context where it doesn't apply. I'm not going to argue with the notion that Node has many poorly written community packages, it does, but this core piece of Deno functionality does not use any.
So why on earth are you using their packages?
Excuse me for asking the obvious, but if they would never pass a technical skills test at the company you work for, why are the people who did pass using code that these maintainers wrote?
It sounds like the right approach is to sidestep them and fork the project yourselves. That way you'd clearly have a much more competent team maintaining it, and implementing all the features you need.
That is if you trust code written by someone of such standards in the first place. Really you should just rewrite it from scratch so that you know it's never been touched by anyone not at the competency level of your elite squad of code monkeys.