The move towards TypeScript 'winning' has been fast, and to everyone's benefit.
The move towards TypeScript 'winning' has been fast, and to everyone's benefit.
Why? I've worked on large codebases in Coffeescript, ES6 and Typescript. Whatever this whole community sings and believes, but Coffeescript still wins for me. ES6 is still trying to catch up but will probably never reach the beauty and ease of Coffeescript. Both are transpilers, only ES6 with Babel is a total horror to manage (just upgraded a large codebase to Babel 7..).
Typescript takes about 2x the time to write if you want to create all your typings properly. I hear you say; only in the beginning, later it will speed up the development process. I've never seen that in reality! I've actually never seen a proper codebase in Typescript. Show me a Typescript codebase not using the type 'any'! In a decent system language you can't get away with that, it's just a fake sense of security.
A good codebase should not be dependant at all by Typescript or whatever hype comes next. Writing a good codebase is IMHO a craft and should not depend on the language or a bunch of tooling. If Typescript is way to go, what about Python, Ruby, abandon it, deprecated? Are those inferior languages compared to Typescript? Typescript is just another hype, very smart play by Microsoft btw.
I can the same way cast value to an Object in Java of NSObject in Swift.
1. One standard typed version of JS (As appose to flow and TypeScript) is a better use of open-source developer time. It also reduces decision fatigue when architecturing new JS projects. 2. TypeScript tooling is fantastic. Using VSCode or Webstorm spoils you. 3. TypeScript is a testing ground for experimental language features. It can shape the direction of future versions of JS. 4. Finally, the language is clearly well liked, in addition to being popular. We can debate the pros and cons of its quirks, but overall, the stats say developer satisfaction is high. https://hub.packtpub.com/4-key-findings-from-the-state-of-ja...
Not true at all. You balance all of this stuff inside your head anyways: this object has this shape, this function takes these arguments, etc. The only overhead is actually writing them down -- which in itself arguably speeds up development because then your IDE knows about them too.
I pushed back migrating from Coffeescript to TypeScript and I consider it one of the only times I was really wrong about a front-end technology.
That's the problem then. I have, and have clearly seen in the real world why it's superior. ES6/Coffeescript can obviously be done correctly, but chaos tends to ensue as the flexibility is abused. Over time it makes debugging/understanding difficult. TypeScript makes changing/navigating large codebases a breeze. In other words, it's much easier to do correctly than ES6/Coffeescript.
Show me a Java project without an unchecked cast... I’m not a CS person but my impression is that sometimes you need these types and they exist in the type system for a reason. No type system is conceptually “perfect” as in there are soundness/expressively tradeoffs. I don’t think using ‘any’ is always bad. Sometimes it’s even right?
But in TS, the main reason for "any" is interop with JS.
A lack of soundness is closely related to the Turing completeness, especially in languages based on HM. In an ideal world you would want a sound type system and not want Turing completeness, but the tooling doesn't exist to make those choices the most pragmatic right now.
I don't know the comparison to system languages is fair though, because the use-case for JS is quite different from system languages.
Javascript (and by extension, Typescript) is commonly used to interface between the user and the network, both of which often are outside the bounds of the type system. Add to that any code that interfaces with plain JS, such as external libraries or legacy code. When dealing with those, it's natural to use statically untyped values and type ascriptions based on reasonable assumptions.
Taking that into account, I actually think Typescript's type system is fairly well-designed for the use-case. The problem isn't really with Typescript, it's just intrinsic to the use-case of JS.
C is clearly statically typed, but among statically typed language it is quite weakly typed.
Of course, relative to other code in that language you can write good code in any language and that is a useful and important skill. If you invest enough energy and craft, you can even write code that compares favorably to good code in any language - the Linux code base is a testament to that. Still, it is a fallacy to assume that all languages are created equal. Nowadays, next to nobody would argue that writing code in Assembler is a good idea. And even though it is now possible to write web apps with C (via webassembly) there is no movement by seasoned C programmers to conquer the web.
> If Typescript is way to go, what about Python, Ruby, abandon it, deprecated? Are those inferior languages compared to Typescript? Typescript is just another hype, very smart play by Microsoft btw.
While the truism "use the right tool for the job" is overrated, it applies here. Untyped, quick to write languages are excellent for small projects. When I'm writing Python as glue code, designing nicely typed interfaces is a distraction. Also, Python, Ruby and Javascript have base types with excellent usability. E.g. when you parse time sheet data, it is pleasant to return [(time.parse('9:00'), 'document project X'), (time.parse('10:15'), 'implement feature Y')]. But when projects grow every structure enforced by the language is a guarantee I cherish. You know, there is this special case in your time sheet parser where you return a (time.parse('23:59'), Null) element, instead of using the empty string, which made the code much more elegant. But months later, when you are refactoring the code calling the parser, you have totally forgotten this behavior and introduce a subtle bug. That's the time where I wish I had a robust type system.
TypeScript is great in this regard, as you can ignore all types if you wish and gradually add them later, when the complexity of the code base calls for it. Or you start with complete type coverage from the start if that floats your boat. Or you never introduce types and just consume JavaScript. Because of that, TypeScript is especially valuable for libraries: It gives the consumers of the libraries all choices. And it's also the reason the success of TypeScript is celebrated that much: Each new TypeScript enhanced library increases the effectiveness of the tool (and reduces the amount of `any` crutches).
Also, I'm sorry but you make some weird comparisons. ES6, Coffeescript, TypeScript and Python/Ruby are 4 completely different things. Not sure why you are trying to compare them and choose a winner.
...
> Both are transpilers
You don't have to transpile es6 if you don't want older browser support.
https://github.com/krakenjs/zoid
Admittedly Flow, not TypeScript -- but 99% the same thing syntax-wise. And yes -- it was difficult to set up and get working comprehensively, but now it's there, it's fairly easy to maintain, and it's invaluable when refactoring, accepting PRs, or adding new features.
Most people using `any` should really be using `mixed` (flow) or `unknown` (ts) which at least force you to check before you use some property of those types.
If we want a clear winner to everyone's benefit, wouldn't we want Yarn to go away and for npm to gain whatever it's missing that makes Yarn relevant?
To be fair, I haven't touched Yarn in years. I switched to it, loved it, and then npm got the package-lock and some performance fixes and I suddenly didn't understand why I'd want to use Yarn.
I'm conflicted because on one hand I strongly believe that we're all better off using the same tools so we can help each other more easily. But that suggests that alternatives shouldn't exist, which stymies innovation.
NPM and Yarn don't have this problem, since they are pretty much drop-in replacements for each other. As long as `yarn install` and `npm install` both get the job done equally well, picking one becomes a personal choice. Every project that adopts a standard package.json is a win for both NPM and Yarn. There doesn't need to be a loser in this case, and diversity is good.
I'm a big fan of ES6 and I haven't been a fan of typed languages for a long time but I'm liking using TypeScript. So are my coworkers.
I tend to view TypeScript similar to CoffeeScript — it brings to JavaScript some features from other languages that are convenient and preferred by a subset of frontend developers. It allows for experimentation in the language, and helps inform TC39 proposals.
In time, I suspect support will coalesce around a specific TC39 process proposal to add type support, it will graduate to stage 3 or 4, get integrated into browsers and Babel, and enthusiasm around TypeScript will wane.
For data, 46% of npm's survey respondents used TypeScript: https://blog.npmjs.org/post/180868064080/this-year-in-javasc...
Do people prefer typed JavaScript over JavaScript tho? I know that I prefer typed JavaScript, especially to write long-term web applications or Node.js server applications, but I don't think there is yet an unanimous shift towards typed JavaScript.
I'd like dynamic typing but without the implicit and dubious type coercion. Like Python.
I keep hearing this complaint, and at the same time I'm wondering why it's a big problem. So you can't find 3rd party libraries that are good enough to fill in the void from the lack of a good standard library?
Given all the constraints, it’s highly unlikely that you find something consistent.
That's a strange choice of example to highlight the sparseness of the standard library.
There's not much I can do with a class that can't be accomplished with a simple function.
I think I've evolved in my thinking over this in the last several years of experience.
That said, Babel now supports TypeScript so you should get nearly the same performance with TypeScript as you did with Flow or even just plain ES transpilation. That way you can do typechecking as a separate step like you would have done with Flow.
GCC startup time is going to be faster than Node.JS startup time, but that's irrelevant. We don't need to restart the compiler on each iteration. You can just use an auto reloader for that.
And since we're real developers writing real apps, hello world is not important to us. We want to organize our code into modules and bundle those to a single JS file that is minified in production. So we're going to process the source code one way or another.
C++ is a funny example to mention because it scales pretty poorly in the compilation time aspect, because it lacks modules. Compiler startup times are good... But it's not really that fun burning all 16 cores trying to compile Qt and still having it take forever. Compare to Go where compilation is so fast most people don't even talk about compilation speed.
All languages compile eventually anyways, even JS. It just compiles in the browser. If you really want a "zero compilation step" experience, you can just load the TypeScript compiler directly in the browser. It's been done in the past for demos.
Interesting, I hadn't considered that. I've always just had a build script (usually in package.json), and run that when I change something (either with an inotifywait loop or manually). It does make sense that if you're instead keeping one long-running node.js process instead of spawning a new node.js instance every time, tsc's slow start-up won't matter as much. I'll have to keep that in mind next time I end up doing typescript work.
I have used Angular, using a long-running webpack process which does angular template and typescript compilation, and I found that to be excruciatingly slow even for small changes, but I'm willing to bet that has more to do with Angular than with Typescript.
> C++ is a funny example to mention because it scales pretty poorly in the compilation time aspect
C++'s compile times are horrible, I won't try to defend it - waiting another eight hours for Chromium to compile because you need a build with debug symbols is just horrible. However, most of my time actually working on relatively small C++ code bases is pretty good; compiling each individual file doesn't take very long, and you only recompile the files which have actually changed, and recompiling one C++ file and re-linking the project takes around 0.4 seconds (unless you're doing something stupid like linking in all of webrtc, which we admittedly do for a couple of projects at work). Compiling a typescript file which just contains `console.log("Hello World");` on the other hand takes a bit over a second. (I know compiling hello world isn't very relevant when your compiler is a long-running process instead of a one-shot thing, I'm just including it because that's what my experience with tsc has been until now.)
Do you happen to know of any good resources for how you would run the compiler multiple times from one node.js process? I imagine webpack maybe does it already, but I would be interested to import the compiler as a library or something, and do some testing to see how big of a difference it actually makes to not start a new javascript VM every time.
https://github.com/Microsoft/TypeScript/wiki/Using-the-Compi...
And of course you can read the source code for Webpack's typescript support.
Sidenote: although it's less popular, I highly recommend looking into Parcel Bundler, it's much nicer to use and has no configuration required. You can, for example, point it at an HTML file with a script tag pointing to a TypeScript entrypoint that includes NPM modules and it will handle compiling, bundling, minifying transparently. And it's relatively quick.
I probably shouldn't have lead with the "not only is it an extra step" thing.
Edit: changed strong to static.
Abstractly speaking, there's no big conceptual chasm that separates a test in a test suite from a test the compiler makes.
A lot of unit tests will revolve around checking types. If you don't have to runtime-check this, you can focus unit tests on semantics and integrations assuming the underlying data structures are correct.
In retrospect, my original response was too terse. Static typing and testing serve the same purpose, which is to make sure your application runs according to some measure of correctness. We shouldn't be setting up one-or-the-other dichotomies — we can have both!
Static types won't help with your application logic, but they will (for example) ensure your function inputs and outputs are the correct types, help document your code and ensure consumers call your code correctly. Unit tests can only do the first one, and it's more verbose and brittle.
All those kinds of tests can be eliminated with static typing. It's true that a lot of those types of errors would get picked up in functional tests, but at least from my perspective it's not great practice to rely on a functional test to catch that kind of change. If your functional test changes it's easy to lose coverage of your basic unit tests that were only happening implicitly.
2. If the tests must be updated whenever the underlying implementation changes it might be testing too much- it's better to test behaviour, not implementation.
const x = "one two" + 3;