Hacker News new | past | comments | ask | show | jobs | submit login

Without Angular, we may very well not have TypeScript today.

The top thing listed in this release (TypeScript doesn't follow semver, btw) is about Decorators. I find the whole story about Angular's role in TypeScript early days to be very fascinating because I don't hear people talk about it anymore (just search "AtScript TypeScript" if you weren't around at the time). It was the Angular team that forced Decorators to be added when it was still stage 0. In exchange, they forfeited continued work on their would-be competitor to TypeScript.

Even without the Decorators thing, Angular was intensely popular and it made a big impact how they went "all in" on TypeScript, pushing a lot of early adoption. I know lots of people that first started with TypeScript because of work on an Angular project.

I think a lot of people don't seem to know/remember how touch-and-go TypeScript was in the very early days. There were many large projects that were all-in on FlowType, and others still that were pushing for Elm, etc. For example, it took quite a while for you to be able to do JSX _at all_.

Today, we just have TypeScript. Well. I do know one company that uses ReasonML (or isn't it called Rescript now?)

---

Historical stuff aside, I'm extremely happy we ended up with TypeScript over the others because the team is so incredibly awesome and dedicated. It's rare you see such a large project so well shepherded by such a talented set of individuals. It speaks volumes that the average tenure on that team is so high. We've seen some public apologies from the Flow team on this topic so I don't feel like I'm talking behind anyone's back if I say they ended up truly not being up to the task of being what TypeScript is today.




One of my most regretted decisions was evaluating Flow vs Typescript and going with Flow. Years later I had the opportunity to use Typescript and it was so nice comparatively. I've enjoyed it ever since. Of course, that was with years of development in its belt so maybe the experience wouldn't have been as nice if I went with it originally.


It’s hard to imagine if you weren’t in the React community at the time, but I feel like most people were pushing Flow at the time and choosing TS was quite controversial. I think it was the combination of Flow being from Facebook, and the “no build step/its just JS with annotations” thing which people made a big deal out of, but I never saw as a big differentiator.

I had a hard time convincing a couple of places I worked to use TS rather than Flow for greenfield projects, but I’d tried them both out and concluded Flow just felt too unstable - the server would consume all my memory and crash and it just didn’t feel like a good dev experience. I managed to convince them by showing them how you could strip out Typescript types in much the same way as Flow if TS did turn out to be a dead end. I also recall having vigorous debates at React meetups where I was the only person in favour of TS haha.

How times changed - you definitely can’t be blamed for choosing Flow at the time though as TS was the outsider. Also MS weren’t such a trusted brand for developers, people still associated them with proprietary stuff like .net/full fat Visual Studio and I think a few people had burned out in the MS ecosystem before and didn’t want to touch their stuff again!


> I think it was the combination of Flow being from Facebook, and the “no build step/its just JS with annotations” thing which people made a big deal out of, but I never saw as a big differentiator.

I put quite some time into evaluating Flow vs Typescript around 2016, and preferred Flow mostly because its type checking was more correct, and its bugs more straightforward. Typescript would happily compile all sorts of incorrect code even with its strictest configs, it was insane.

I eventually found my happy place with Scala.js.


This is true. I think TS arguably took a more pragmatic approach which allowed you to adapt existing codebases and coding styles more easily, at the expense (initially) of type safety. Obviously there have been many improvements since then


I made the same mistake, though our transition to TypeScript was actually very smooth. We just set up Babel to handle both, then converted one file at a time. Flow files functionally became untyped JS files until they were converted. And the syntax/semantics were close enough that converting code was really easy


Same. I spent the next few years doing major refactors from Flow to TypeScript (the largest that's public was for Insomnia: https://github.com/Kong/insomnia/discussions/3654).


Interestingly, both flow and typescript have roots in OCaml/F# respectively. Flow was written in OCaml and the creator of Typescript was on the F# team at Microsoft.


> creator of Typescript was on the F# team at Microsoft.

I actually think the bigger driver for TypeScript was Anders' history of working on C# and Delphi before that.


we started with Flow and moved to TypeScript a few years ago; converted 100k lines of code primarily with sed via regular expression find/replace; even then TypeScript was better but 80% of the better part was the library of available typings--Flow's support for lodash types was awful in comparison and we used lodash and lodash/fp all over the place


Flow was (and still is) awesome as a concept, but its main problem was that it felt as a side-project, which was supported for internal Facebook cases, but not really for open-source. TypeScript (back then) was a simpler language, but had a lot more manpower, which resulted in faster bug-fixes and more coverage of libraries.

If Flowtype had more resources from Facebook it could still be the dominating language


Don't worry - the Twitter web team also made this mistake. But they made it at a time when TS was popular instead of earlier when the two were equally popular.

Even well after TS was clearly the better option (as in 2022) the twitter web team opposed anything being done in Typescript like separate modules that would be a dependency of the web repo.

At least you recognize the better direction now.


With how much respect I have for TS now (its close to the gold standard in several categories for me), that would be a..... frustrating setup for me these days. TS just gets so much right, and is really a pleasure to work with IMO.


I'm curious what criteria you used to pick Flow vs. Typescript.


We picked Flow because we were using React, and Flow was from Facebook, so we assumed the support/integration would be tighter than with TypeScript. It also had some appealing goals like stronger soundness, and a greater emphasis on type inference than TypeScript had at the time

The main reason we switched was the tooling. The language server was slow in the best of times, would crash constantly, would memory-leak all over the place. Some of our devs stopped running it at all because it was so broken all the time. Then I tried out TypeScript and the speed and stability were breathtaking, and we never looked back.


I personally picked Flow because it was (and still is probably?) a much sounder and stricter type system than TypeScript.

However, keeping up with the constant breaking changes (I helped maintained a few complex flow typedefs) led to me getting disenchanted and burnt out with Flow.

Also, at one point a change was introduced where most (or all) internal errors would just cause a type to decay into `any`s, which frustrated me a lot.

I don't hold it against Flow though; its only customer is the internal React team, and it's a 0.x software too.

We've migrated our code to TypeScript later and it was a bit smoother sailing (although the typedefs for a few popular react ecosystem libraries were just... Abysmally wrong, it didn't matter at the end of the day; it was still easier).


Flow is more sound in a lot of ways (e.g. exact object types, by default!) but it also has huge holes (e.g. it has no equivalent to --no-implicit-any, the single most important strict flag in TS). Neither is strictly more sound than the other.


for a lot of people it was some combination of:

- Flow has more adoption (it did, for a while, in the OSS sphere)

- Microsoft is evil (remember, this was before everyone was using VS Code and loving it. (Also, tautologically, TypeScript has been one of the biggest things that changed this public perception for the people I hang around))

- Facebook is awesome (oh, how times have changed...)

- Flow has total type soundness as a goal (from the beginning, and through to today, TypeScript still lists this as an explicit non-goal)

- You literally cannot use React and Flow together (it didn't support JSX for what felt like an eternity and Flow did from the beginning (I think?).

- Flow had exact object types (TypeScript _sorta_ has this today, but most people don't know to turn it on because it isn't in the strict-mode family: exactOptionalPropertyTypes)

- Flow had more features (and was faster)

- DefinitelyTyped didn't exist yet, and it was easier to find types for Flow (but, let's be real, both had nearly nothing compared to today)


Total type soundness is not a goal of Flow.

For example, array bounds are not considered. Flow considers this program to have no errors, but TypeScript (with the correct option enabled) will:

  let m = [1, 2, 3];
  console.log(m[4].toFixed());
Also, DefinitelyTyped itself launched before Flow (2012 vs 2015), so the timeline on that point isn't right.


TypeScript tries to be sound too. It wouldn't really make sense to write a type checker if that wasn't your goal. As the person who wrote the "100% soundness is a non-goal" line in the design goals document, that's there to serve the same role as "Flow sometimes has to make a tradeoff" in the Flow docs in terms of clarifying whether or not 100% soundness is a design goal. For both projects, the answer is "no".

It's unfortunate that people have, over the years, decided that just being upfront about this fact means that TypeScript has a vastly different prioritization of soundness than Flow. We don't; both checkers use soundness as the default assumption when designing behavior.


> Flow tries to be as sound and complete as possible.

> https://flow.org/en/docs/lang/types-and-expressions/

That's what I was talking about re: Flow.

That's a really insightful comment you make about the "turn of the phrase" between how the two marketed themselves. Super interesting stuff.

also, apologies for messing up the timeline on the DT repo. My memory failed me there. Has it been that long?!?


I am still attracted by Flow which seems to have a simpler and stronger type system. However, Flow seems a bit unstable and the lack of support for TypeScript declaration files and widely used TypeScript syntaxes are stopping me from switching to Flow. I opened an issue for bridging the syntax gap between Flow and TypeScript [0]. Flow v0.201.0 renamed `$Partial` to `Partial` making Flow a bit more compatible with TypeScript. I hope it is just the beginning...

[0] https://github.com/facebook/flow/issues/8989


As an "old person" it still weirds me out to see Microsoft get so much praise for their open-source developer tools


TypeScript could be used with React at least since 2015, that's when I first used that combo in production.


it's going to be really hard for me to find now after all these years but there's a video somewhere on YouTube of someone at a conference showing their first attempts at getting TypeScript to work with JSX involving lots of special comments that they would compile out with babel or something (it's been a few years, hopefully I remember that correctly). It was pretty extreme (and cool!).


Flow still has some better sides:

* first class opaque type support

* exact object type

* correct variance, sound liskov oop

* no transpilation support (/*: */ and /*:: */) - so simple, so powerful; jsdoc ts doesn't compare, you can't import type star, when consuming libraries you have to increase maxNodeModuleJsDepth and other shenanigans; in flow you simply have access to all flow type language; why they don't want to do the same with ts is beyond me, it's like half a day of work to do it?

* nominal types for classes, structural for the rest - as it should be

* correct spread matching runtime behaviour

Flow is under active development. They recently completed ~2 years of work on local type inference which is a big deal. But dev team is not interested in external contributions - quite opposite to how ts development is done.

I did switch to ts as well but do miss above.


Great list!

Related to your point on supporting 0-transpilation workflows as a first class citizen, is the fact that Flow was explicitly just type annotations & checking, and aimed to introduce 0 runtime constructs.

This is something Flow did from the beginning and TypeScript eventually established as a non-goal after already implementing several runtime constructs that they can no longer afford to remove for backwards compat [1].

Though interestingly enough, Flow themselves recently announced they're going to start introducing runtime constructs, which is an interesting plot twist [2].

[1] https://github.com/Microsoft/TypeScript/wiki/TypeScript-Desi...

[2] https://medium.com/flow-type/clarity-on-flows-direction-and-...


In another plot twist TypeScript is supporting the Types as Comments TC39 proposal that would provide a true 0-transpilation workflow.

https://devblogs.microsoft.com/typescript/a-proposal-for-typ...


I remember doing a head to head comparison between Flow and Typescript back in 2015 or sometime around then, and flow came out top at the time. Main pull for flow for me was strict null checking and disjoint unions, which typescript lacked at the time.

About a year later typescript got strict null checks and discriminated unions, and from that point on typescript just kept improving, the community type defintiions kept getting better, and flow felt like it was stagnating and had lots of performance issues (esp on windows machines).

Flow actually still has a few notable features that typescript still lacks but are often asked for. For example, flow as `Exact` types that ensures that an object doesn't have excess properties throughout its lifetime - ergonomics are a bit awkward though.


Typescript in strict mode doesn't allow excess properties in an increasing number of situations. Typescript is still more structurally typed than nominally typed so there's no easy way to opt-in a specific type to stronger checks than average. The ergonomics are obviously different between Typescript and Flow. There are existing practical workarounds today to get more "nominally exact" types in Typescript such as using "brands" of various sorts (the most common is adding a private unique symbol to a type), though the ergonomics of using such branded types is also its own sort of awkward.


Those excessive property checks are pretty limited to basically the construction of object literals, and it does it because its normally an error if you have a very explict type but your literal expression doesn't match it. Typescript really does nothing to enforce anything around excess properties except for that narrow case.

Branding doesn't really enforce anything except what the user asserts is the case. Its not the same thing.


This was fairly early days (I want to say early 2016?), so its fuzzy now (and pre VS code going mainstream which has lowered TS friction pretty significantly) but I think a lot of it was a fairly basic pros/cons list with a lot of reading peoples opinions of using each technology. I think my ultimate reason was that Flow was comment-based and so was technically more "rip out"-able if I changed my mind later.

EDIT: oh, also as someone else mentioned it was a React project, so I'm sure that played a part.


Flow allowed gradual typing of the project and Typescript forced you to convert everything at once(at least the first versions of TS)


So it would seem that going with the flow turned out to mean not going with Flow; how confusing![1]

I went with TypeScript early on because the compiler chain felt better integrated than the alternatives. No messing with chains of babel translators and source mappings; just use one tool. Maybe I liked the syntax better, also. Although as I recall, in the beginning, somebody my company interviewed had set up TypeScript using Babel, and it was all very over-my-head and impressive. He turned out to be too good to work for us, but some of his ideas really stuck with me.

[1]This is why I dislike cutesy names for software projects. Just call it FacebookTypeAnnotatedJavaScriptFrobulator3003 (FTAJSF3003) or something.


> One of my most regretted decisions was evaluating Flow vs Typescript and going with Flow.

What caused you to choose Flow over TypeScript?


I remember this well, too.

Ironically, I think that angular is the framework that benefits least from actually using TypeScript. There is a separate templating language that's only type-checked if you set the right compiler options. JSX is much better suited for that. Being OOP like angular, it often requires opting out of null-safety or init-checks, because something is late-initialized. Having mutable instance state results in less opportunities to be more strict with typing.

Its good that the TS team decided to align with the ES standards. Initially (talking like v0.8.0), I had the impression that they're building a "C# for the web", being incompatible with ES. Maybe that's why enums and namespaces were added and initially, the boolean was named bool.


Enums have been proposed for JS for quite a while (there was a sort of enum in "the lost version" ES4 and a TC-39 proposal stuck in Stage 0 for years now [1]). Enums have always had relatively simple JS output that resembles a somewhat common pattern in JS. It was a "standard", just never really a deeply adopted "standard".

What's today called "namespaces" in Typescript was originally called "modules" and then "inner modules" (to differentiate from "exterior modules") and is a tiny simplification on a JS pattern that was extremely common at the time of Typescript's inception called at the time "IIFE modules". "namespace" is a very C# name chosen in desperation (when it became clear that "exterior modules" were the present not just the future of the language and "interior modules" was too confusing a term to live), but it's a very old (and used to be extremely common) JS pattern that TS gave a tiny bit of syntax sugar to. It was a "standard" that existed at the time that was (rightfully) killed by AMD/UMD/CommonJS/ESM, but it is hard to fault the Typescript team at the early 0.x days thinking the "Stage Wild" JS pattern would possibly live on for many years to come. (This is also relevant to the patch notes for Typescript 5.0 as 5.0 is the first version [!] to itself be written as [proper/"exterior"] modules rather than namespaces. There are some interesting stories, including in these release notes for why that took so long to transition and what the performance benefits have been post-transition.)

Even those things that didn't seem like ES standards have some history as JS "standards". It's not like TS 0.x/1.x didn't support "standards", it is more that the TS team mostly decided to focus more on later stage ES standards (more likely to be accepted by browsers) rather than trying to "prollyfill" Stage 0 and "Stage Wild" standards.

[1] https://github.com/rbuckton/proposal-enum


I remember this well.

From the outside, it seemed a fantastic example of collaboration between two separate (competing?) teams. It took humility and pragmatism for the Angular team to abandon AtScript and recognise TS as the better long-term bet.


I have often thought that it must have been tough to be on the Flow team. It was pretty good, and absolutely would have been "good enough" to catch on if it weren't for TypeScript. But ultimately the better language won.


Flow ultimately served only Facebook purposes and their work and the evolution of the language wasn't on par with TS.


And it doesn't hurt that the TypeScript team is so great. We've seen some public apologies from the Flow team on this topic so I don't feel like I'm talking behind anyone's back if I say they ended up truly not being up to the task of being what TypeScript is today.


Any links to their apologies? I don't understand why they apologized.



yes exactly.

The only other context I'll add is for people shipping Flow that I knew at the time they felt that this announcement felt like it came about two years too late. I had already switched to TypeScript long before because, in part, of the things they're apologizing for in that article which were evident long before being said out loud. I say that with great reverence and respect for the people that worked so hard on Flow, by the way, but that's the situation I experienced.


AtScript was always stillborn, and the Angular team absolutely could not have made a competitor to TypeScript.


Agreed, but the point I was making here is that Angular itself was very far from stillborn, it pushed early adoption of TypeScript really really hard which did wonders for TypeScript to be taken seriously.


Wonder why they didn’t go with the other google language Dart

Too foreign to frontend audiences? It has a lot of fans in flutter


There was AngularDart, don't know what happened to it.


Publicly it's dead, but it's alive and well and constantly getting updated inside Google.


>Today, we just have TypeScript. Well. I do know one company that uses ReasonML (or isn't it called Rescript now?)

One company outside Meta?


There's definitely a few around that are using ReScript; we've been using ReScript for production services for a bit more than 2 years now at Autobooks.

https://rescript-lang.org has a list too


yes! haha. They love it. I ping them and see if they want to identify themselves.


FB migrated all of its ReScript to Flow and deleted the ReScript.


> Without Angular, we may very well not have TypeScript today.

Typescript was started at Microsoft by the guy who designed Turbo Pascal and C#, so completely independently from Google's Angular team. Angular had its own "AtScript" and eventually ditched that. Typescript had experimental decorator support well before Angular Team moved from AtScript, because it was a ECMAScript proposal.

Angular had zero influence in the design or success of Typescript. Typescript however does support JSX optionally so one can claim that React DID influence Typescript's design decisions.


(I have worked on the TypeScript team since before its initial release)

While it's true that TS would have been started with or without Angular, I think OP is largely correct in the influence that Angular's embrace of TS had in TS's long-term success.

It's difficult to see these days, but if you were watching TypeScript's adoption numbers back when Angular made its TypeScript announcement, there is a marked inflection point when that happened. I was running lots of charts and graphs at the time tracking all kinds of data, and in every graph, you could see the Angular announcement in the chart; it's where the line went from kinda slow and linear to kinda fast and exponential. It was a true discontinuity in the second derivative.

We can't run history twice and see what would have happened without Angular, but I think the quantitative impact in this timeline is undeniable.


I chose TypeScript for a large project for the first time in early ~2018 and had no idea how much history I had missed. I presumed that the adoption was the other way around and that TypeScript was chosen because it fit the project's needs, but just as grandparent and parent suggest, AtScript was very much a thing.

Talk excerpt talking about Angular directives ~8 years ago! https://youtu.be/lGdnh8QSPPk?t=275


Even if that's true (it's definitely not how it was depicted at the time at conferences and from people on the Google side).. the point stands Angular was absolutely huge for it's day and they pushed TypeScript really really hard. It was a truce between two huge companies and it made waves in terms of people trusting Microsoft.

I have personally never been one of those mega Microsoft haters but I witnessed shouting matches in the office from people that we're hotly opposed to TypeScript being added to the codebase against others using Angular as a core motivation in many of their counter-arguments.

I'm super glad we have TypeScript one way or the other because the team is so dedicated to OSS.


> Even if that's true (it's definitely not how it was depicted at the time at conferences and from people on the Google side).. the point stands Angular was absolutely huge for it's day and they pushed TypeScript really really hard. It was a truce between two huge companies and it made waves in terms of people trusting Microsoft.

Angular.js was huge, by the time Angular version whatever because it was always changing, figured out what it wanted to be, most front-end developers already moved to React.

What Microsoft product uses Angular? Doesn't Teams uses Angular.js but not Angular? and what does a Google conference has to do with Microsoft? Nothing.


> Typescript had experimental decorator support well before Angular Team moved from AtScript

Do you have a source for this. My memory isn't so good but I seem to remember that the Angular team pushed to get this Stage 0 proposal implemented even though the TypeScript team usually waits until Stage 2 or 3 to implement.


Typescript was born of JScript. Check the history and the docs.


> and others still that were pushing for Elm

Still pushing for it. TS is like make-up on a pig, compared to Elm.

> I do know one company that uses ReasonML (or isn't it called Rescript now?)

Re* is also a better alternative imho. Better interop with JS/TS is very nice. But in place one could use Elm, I'd say it certainly wins in the "clean" reward.


god just think how good life would be if we had all switched to elm or reason instead.


Elm was never an option with how hard it is on "no js" policy


If only Elm was infinitesimally less pure.


there's not a day that goes by that I don't think about this


Yep. Frameworks play an important role in end user (developers) helps deliver software as quickly as possible.

Just like without Rails framework, we may very well not have Ruby today.

Also, without WordPress, we may very well not have PHP today.


True, Angular was crucial for adoption of TypeScript 5+ years ago but I think the community would've migrated nonetheless.


for sure for sure. that's kinda the point though: they already were migrating... to Flow. Lots of big projects are on the list that had to change course later because TypeScript won:

- Yarn

- Jest

- Luxon

- Gatsby

- Expo

- Styled-Components

- GitKraken

- GraphQL-js

and that's just off the top of my head. I'm sure there were many more.


Do you have the impression that Flow once had greater adoption than TypeScript, or that there was a movement from TypeScript to Flow? I think it was always behind in adoption, but of course, some projects used it anyways. From my memory, Flow always felt like the less conservative cousin and it was tempting to use it, but TypeScript always was the safer bet.


I have to disclose my potential bias here because I am these days very involved in the TypeScript world (with Michigan TypeScript). That said, I would never hide the fact that I was once a die-hard Flow person that.. died hard, haha. (and I'm very glad I did! more on that later)

In the very early days (in every circle I was in) Flow was ahead by every measure (known examples, excitement, adoption, features, speed, etc). You could point to real live running apps like GitKraken and Discord (hopefully my memory isn't failing me on those) that where shipping Flow very early. And you could use JSX! At the time there was literally no known project (especially OSS) actually shipping TypeScript. Not from Microsoft and not from anyone else. It was hard to tell if TypeScript was more of "embrace extend extinguish" (obviously with hindsight we can be absolutely certain that it wasn't that (unless we're talking about a decades long "long con" lol))

But there's something I could never have anticipated at the time that's more important to me today than any feature of the language:

The TypeScript team have done a breathtakingly amazing job of carrying the project through the years. TypeScript, as an open source project, is an absolute triumph: and I think it has everything to do with the people behind it.

At this point TypeScript is "good enough" in every way that really matters. If they consciously stopped developing the language and just focused on performance and bugs I think we should all call that a success. I really believe it's been handled _that_ well.

Meanwhile Flow went the other direction and there were bugs (in the 0.30 era, approximately) that had people pulling their hair out that were caused by the impedance mismatch of them making it for Facebook first and the rest of the world last. As far as I can tell, this really never changed (or at least, if it did, then maybe it was "too little too late").

Meanwhile, it seems like TypeScript has been managed with the literal opposite mindset: putting us in a situation where only one major project is left using Flow... React.

There are other projects like ESLint that have been... how do I say this in a not bridge-burn-y way... surprisingly reluctant to realize that TypeScript isn't some passing fad. But I'm confident that they're going to have their wakeup call sooner or later. The culture of JavaScript-land is just not loyal enough for gatekeeping a technology like TypeScript. Look at webpack. We all spent nights and weekends for years gaining knowledge on how it works and weeks per year getting familiar with it, then esbuild happened and we threw webpack away overnight like it never even happened. I believe the same fate awaits projects that deny the necessity of writing in TypeScript at this point in history, with the possible singular exception of React.


We have WASM dude. But TS people are in TS bubble for what it's worth.


WASM and TypeScript don’t really compare or compete. I’m not sure what you’re saying.


Until WASM can touch the DOM you’re still going to need JS (and hence, TS).


In fairness, rust-in-wasm has pretty complete DOM bindings. You can quite easily write DOM manipulation code in Rust without ever touching JS/TS. Whether that's a good idea is another matter.


How does that work?


web-sys[1] generates the binding code using the same IDL files that browsers use to generate their JS bindings to the C++ doing the actual work.

[1] https://github.com/rustwasm/wasm-bindgen/tree/main/crates/we...


You still need to run JavaScript functions to manipulate the DOM. "without ever touching JS/TS" seems misleading as that implies "no JavaScript code is executed".


When I read "touched" I don't think "executed". I think "edited". There is C code executed when I run JavaScript, but that doesn't mean that I had to touch it. Similarly, all the JS run when accessing the DOM from Rust is generated by the library. The user of the library doesn't have to touch it.


And objects. And so many more things.

Wasm is a cpu or low level operating system and not programming language


It's not worth anything. Are you writing raw WASM?




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: