Hacker News new | past | comments | ask | show | jobs | submit login
Migrate Jest to TypeScript (github.com/facebook)
261 points by whatever_dude on Jan 16, 2019 | hide | past | favorite | 125 comments

Interesting move. If major projects within Facebook are migrating away it seems pretty likely that Flow is on the way out.

Which I think would be a good thing, it seems like a lot of projects and libraries haven't fully embraced either because it's unclear which to choose. In this case I don't think the "competition makes them better" aspect outweighs the downsides of having a fragmented community.

There was a time when TypeScript was woefully incomplete when compared with FlowType. When I first had to choose between them, the thing that sold FlowType to me was how it handled null checking, but I was also impressed with the rich type system with advanced type inference.

Then of course, TypeScript greatly improved and added many of those features. The Flow type inference engine is probably still more advanced, but TypeScript does good enough, and has good developer ergonomics all across the board. Hopefully Flow improved since I last used it but if not it regularly ate tons of memory, was difficult to configure, and had poor IDE integration. So in the modern TypeScript world it's hard to choose Flow despite it's potential advantages, imo.

So, I was one of (or I suppose the only...) person in the linked issue arguing that competition is useful, and that it makes sense for Facebook's products to be tied into the same ecosystem.

As others have mentioned, when Flow was first launched, TS had an extremely limited type system (e.g. no null checking, no union types). Of course this has improved a lot over time, as the two have converged, but there's still a long way to go for either project to allow JS reach the level of correctness and expressiveness of, say, OCaml or Haskell.

Flow has consistently for the past few years been bringing new ideas to the table from this algebraic data types background, which often have ended up proving to be good ideas, and are in various stages of trickling down to TS.

I worry that if the ecosystem becomes completely dominated by TS, the overall focus will end up back where TS started: rudimentary OOP inspired types, without the underlying goal of overall correctness, which Flow strives for, while TS openly eschews in favour of "pragmatism".

You can’t have the same level of correctness as ocaml if you want to maintain the compatibility with JavaScript. Typescript type system is unsound for this reason. You can’t have anything approaching ocaml correctness when in typescript all objects with the same shape are interchangeable.

Yeah I realise you'd never reach the same level of soundness due to the limitations of the underlying JS (although presumably you could get close with a subset?). But that's why it's an interesting challenge, and I think what Flow has shown is that it's possible to get a lot closer than had previously been imagined.

If everyone just accepted the argument 4 years ago that "JS will never be sound" then maybe today TS would still just be Java style `interface` annotations for classes. It's not like the Flow team has reached a ceiling at this point... there's still plenty on their roadmap that would continue to improve soundness and expressiveness.

> You can’t have anything approaching ocaml correctness when in typescript all objects with the same shape are interchangeable.

Could you elaborate? Flow has recently switched to exact objects by default[1], which I would have thought would be enough for a sound approach?

[1] https://medium.com/flow-type/on-the-roadmap-exact-objects-by...

For example in typescript this is valid:

    type A = {name: string}
    type B = {name: string}
    function print(obj: A) { alert(obj.name);}
    let a: A = {name: “hello”};
    let b: B = {name: “world”}
This is because of typescript structural equality and I think that the same applies to flow given your link. Obviously if I want a function to accept an email I don’t want the same function to accept an address, but in typescript you can’t guarantee it because you have no way to get rid of structural equality as far as I understood.

Ah I see. That can be achieved since Flow 0.51 with opaque types[1][2]. It seems like TypeScript hasn't yet caught up with this functionality[3].

[1] https://medium.com/flow-type/hiding-implementation-details-w...

[2] https://flow.org/en/docs/types/opaque-types/

[3] https://github.com/Microsoft/TypeScript/issues/15807#issueco...

Yup that seems to help.

I'm certainly not well versed in OCaml, but my understanding is that it is also structurally typed. This particular example would also be permitted in OCaml, correct?

No, records are nominally typed in OCaml, thus the two types `A` and `B` would be deemed incompatible.

But objects in OCaml are structurally typed (well, row typed).

IIRC, the writing was on the wall for flow these last two years. Aside from a few core users, it was never really as popular or as responsive as TypeScript was.

More a fad than the future, I suppose. But at least flow brought some valid ideas to the table, e.g., strictness.

> More a fad than the future, I suppose

I think that could be seen as a bit harsh, especially in light of the follow-up sentence. What Flow added to the JS ecosystem is probably the future, it's just that the implementation of that future seems to be TypeScript.

I recall the Nomad being described as the future too, and the iPod described as some boring "friendly" implementation of that future.

TypeScript is basically only good now because of the competition. Earlier versions were pretty darn awful.

These days, yeah, you're probably right that having only one might be better. Hopefully WebAssembly and languages running on top of it will create the awareness and competition required to keep things moving.

That x10 for the frontend component ecosystem.

The TypeScript team really made the right call by adding support for TypeScript syntax to Babel. Ever since that got merged, the floodgates have opened: more and more projects support TypeScript by default or practically only requiring you to flip a switch, making the cost of adopting it (if you don't need to spend time learning it as well) practically zero. No matter how small the project, if I start a new one today, it will be written in TypeScript.

Adoption is now at a point where it is exponential: more projects adopting TypeScript, resulting in more typings being available, resulting in more projects adopting TypeScript.

If there's one thing you can focus on to learn as a Javascript developer in the near future, I'm sure it is TypeScript.

I just started a new project in Vue (which is new to me), and was sad to discover Vue doesn't do TypeScript out of the box.

I definitely see the use case for TypeScript in my project, though: I'm dealing with lots of different types of data. It's useful to know what I've got in my hands.

Well, that's part of the opened floodgates: Vue 3 is being written in TypeScript, so that should get a lot easier for future projects as well.

It's not quite OTB but with Vetr and and such it's the best worst experience. By that I mean, as the worst TS experience it's miles ahead of tooling for say.. Python.

That being said, Vue... Oh Vue. It settled on its own string template syntax that never got the tooling love of JSX. There have been efforts to get them typed, but those efforts never quite rounded second. Lack of typing in the Vue templates seems to be a sticking point for many.. I don't believe they are long does this world; JSX is the future for Vue.

I strongly agree with your point regarding Vue template strings and JSX being the future of Vue.

Coming from React + TS projects, Vue + TS is a lesser experience in many ways. Another such way is the community’s infatuation with exporting raw object literals for component definitions, and forcing you to defy common language idioms to support them hoisting this object literal into a component context.

> I strongly agree with your point regarding Vue template strings and JSX being the future of Vue.

I wonder whether that's really true. Most adoption of Vue is from after React and JSX were a thing, and many of the Vue adopters (or at least the ones I encounter online) are adopting it because they found React to complex, or had trouble collaborating with their designers. That sounds like templates are one of its main selling points, especially when compared to React.

I noticed that a lot of Vue users where coming from PHP and Laravel, where string templates are the norm and familiar.

I come from Angular and I have no problem with Vue templates. I have a problem with Vue's tight coupling and lack of injectable services.

I don't have a problem with React either. I try to avoid PHP.

Works fine for me in VSCode using vetur.

vetur doesn't give you cross-module type checking

As an uninformed typescript dev, can you explain to me how TS Babel support changed things? I understand its mechanical implications, but I don't see why it would matter for adoption.

For example, it made it much easier for projects like Create React App to add optional support for TypeScript. When they added support, that just involved adding an optional extra step to the compilation process (checking whether you violated the type constraints) to make sure you actually get the benefits of TypeScript. Other than that, though, TypeScript projects using CRA use the exact same infrastructure when they use TypeScript, and the compiled output should be similar.

Before, this would have involved replacing Babel with TypeScript for transpiling. This means projects could have slightly different results depending on whether they were using TypeScript or not, increasing the surface area for bugs and adding an extra step to the debugging process.

Doesn't create react app use webpack behind the scenes?ts-loader already worked pretty well? Not sure how that affected anyone using Babel In a built pipeline, but the announcement made it sound like there were tons of people doing bespoke balbel-only builds.. Have not experienced that myself.

Yes, it uses Webpack. Its TypeScript support does not use ts-loader, which would be used in place of Babel loader - which would affect the team behind CRA, who would now have to maintain two sets of documentation, ask bug reporters whether they use TypeScript, etc.

TypeScript support as its implemented in CRA just uses Babel like it did before, with some minor modifications such as also passing it .ts files. In parallel, it also runs the ForkTSChecker plugin for Webpack, which notifies you of type errors you made - however, it would work just the same if that plugin was not activated. Hence, there is far less divergence from regular CRA projects.

Babel is a commonly used plug-in Webpack though. So I am guessing all projects that used Babel/Webpack got TypeScript support for free. It’s a TIL for me, definitely going to have to look into this. Sounds exciting.

Note that "TypeScript support" in Babel means that Babel can now strip the extra syntax that is part of TypeScript applications. It doesn't actually parse them.

A way to think about it is to consider TypeScript to be a linter, like ESlint - but one that you can help by annotating your code with e.g. the types of values you expect it to get passed. Babel can now strip those annotations before it transpiles your code, but you still need TypeScript to do the actual "linting". See https://vincenttunru.com/TypeScript-vs-Javascript

It’s more than a linter though. The Typescript compiler can handle the most common usage of Babel, namely targeting older runtimes.

If you set the build target to ES5 you can still use modern features like async/await and it will rewrite them using a regenerator function that runs on older platforms.

Sure, it can do that - but in CRA's setup, it doesn't; Babel handles that for you. Babel's TypeScript support allows CRA to re-use its Babel pipeline, and the linter metaphor was meant to help people understand that.

Like most metaphors, it's not a one-on-one match.

It's easier to plug it in because there's a lot of projects already using babel, so you just need to add a transformer. Previously you'd need to add a new step to your compilation process using tsc, which could be very difficult depending on how you built your project, especially if it wasn't Webpack-based.

For example, you _could_ use TypeScript before with React Native. But it was convoluted: there were 3 different way to do it, none of them perfect, and all really brittle. But with Babel 7, you just add another transformer to your babel file and bam, it's treated as a first class citizen. It's literally a one line change.

Yesterday's post about migrating to typescript [1] explains it well.

tldr: This release meant that adopting TypeScript no longer meant buying into the entire TypeScript ecosystem and that we could keep using Babel to emit JavaScript. More importantly, this meant that we could actually use TypeScript as a type checker, and not so much as a "language" per se.

[1] https://davidgom.es/porting-30k-lines-of-code-from-flow-to-t...

I think it’s also for themselves. More and more the TypeScript devs can focus on the typesystem and less on the whole ecosystem of deploying Javascript.

I can imagine a day soon when Babel is integrated into tsc to do all of the non typesystem stuff.

I also can imagine the TS team continuing to improve Babel support to a point where TypeScript is “just another plugin” for Babel. At which point tsc can be deprecated.

The less the TS devs have to maintain the more they can focus on their core value add.

I like TS. I really do. It makes life nice and easy to catch bugs quite quickly and also makes you think about your code quite a bit more (which I guess makes you a bit slower but it's important enough so it's ok).

What is annoying is when you are stuck on something and can't continue because you can't figure out the type of a specific object (and you've disabled any / or you are on the strictest settings).

I was recently stuck on ReactJS + Redux + Redux Saga and it took me a while (~ 1 day) to figure it all out (and I'm still not 100% sure if I did it right). It was fine when I disabled the strictest settings for a bit but it's definitely annoying (asking for help in Typescript, React, Redux, Saga and elsewhere didn't really help at all).

I basically do two things to make sure type checking doesn't slow me down:

1) Use emitOnly: true. This means that if your code has type errors, it still compiles. And you can fix the type error later.

2) Never use any directly. Not all anys are equal. Some are there because you don't have the time to figure out a proper type annotation. Others are there because you can express a proper annotation, but think that it's just not worth the effort. And some anys are there because the type system is not capable of expressing the type you have in mind.

What you want to do is to clearly annotate your intention when you're typing something as any. So what I do is to simply disallow directly using any, and instead, use a few global type aliases that better communicate my intention:

  type $FixMe = any // Fix this type, preferably before accepting the PR
  type $IntentionalAny = any // This `any` is intentional => never has to be fixed
  type $Unexpressable = any // TS cannot express the proper type atm
I often put these aliases in a defs.d.ts file and use them instead of any.

> What is annoying is when you are stuck on something and can't continue because you can't figure out the type of a specific object (and you've disabled any / or you are on the strictest settings).

In VSCocde I can hover over variable names to display the type of an object in a tooltip. I assume this information is available for other editors as well via the typescript language server.

Also in VS Code you can click F12 to go to the definition. When importing something new, I will often do this & then spend time reading through all of their type information. This often makes amazing documentation!

When TypeScript first came out, this really helped me learn JavaScript & DOM types that browsers treated differently. It also helped me learn to write cross browser compatible JavaScript without depending on jQuery.

What is annoying is when you are stuck on something and can't continue because you can't figure out the type of a specific object

Funny, but that was the biggest impediment to big refactorings when I've worked in dynamically typed environments without type annotations. (A decade in Smalltalk.)

I much prefer TypeScript than JavaScript, but TS can still allow shitty code, such as:

* Using the type 'any'.

* Using the immediate value `undefined` (JS is mental in the fact that it has two kinds of null... and with TS there's really no excuse for using this one, however TS compiler doesn't complain).

* Using very ugly, or very easy to be misleading, typeguards (granted, TS doesn't have decent typeguards, see https://github.com/Microsoft/TypeScript/issues/28337 ...).

For these reasons, I applaud JS people moving to TS. But I will not recommend any other people (non-JS) to use TS at all.

This hasn’t been accurate for at least 2 years.

- Use the —noImplicitAny flag to prevent implicitly using any (and if you really want — I don’t think you do, but you can — completely ban any with TSLint)

- Use the —strictNullChecks flag to promote null and undefined to explicit types

Or, use —strict to do both of those and more.

Example tsconfig.json: https://github.com/bcherny/json-schema-to-typescript/blob/ma...

Btw, what specifically is indecent about TS’s type guards?

> and if you really want — I don’t think you do, but you can — completely ban any with TSLint

I dunno, on top of the correctness argument: if you successfully write a codebase without any in it, and assuming your data types and algorithms are sane, then the type stability probably would likely result in really good performance.

> Use the —noImplicitAny flag

Welcome to reality! When you do this in any decently-sized TS codebase, you want to kill yourself, because the "smart" devs that started the project didn't do it at the beginning, and fixing it now would take you a man month, in order to be able to enforce it moving forward.

> Use the —strictNullChecks flag

My previous reply also applies to this one, plus: you can still compare against undefined when using this flag (we're talking about unreadable code... even if comparing it with undefined wouldn't make any sense in a codebase with structNullChecks enabled, it's not a compiler error).

> Or, use —strict to do both of those and more.

My gripes above would only be solved if these strict modes were the default. Otherwise shitty and unfixable (read again: man months for a normal project) typescript code keeps being written.

> what specifically is indecent about TS’s type guards?

How about you read the link I posted?

I’ve migrated a pretty big codebase to TS, and then again to noImplictAny. One suggestion is to turn the flag on, migrate a few files, then turn it back off. When you’ve migrated a decent number of files, turn it on everywhere. For a really large codebase, you can do what companies like FB and Google do, and turn the flag on, then codemod every error to suppress it (either with @ts-ignore, or a type assertion). Note that you’ll have to follow a similar workflow for any language-level update- it’s not at all specific to TS.

Re: type guards, Daniel and everyone else in that thread gave a really reasonable response IMO. I think you might just be misunderstanding TS’s design goal of not affecting runtime behavior?

You point out issues that are already solved. It's a people problem you have now :) no amount of configuration is going to fix that.

Also strict has been the default for quite a while!

> Also strict has been the default for quite a while!

That would prevent anyone to rename a .js file to .ts and compile successfully. Which I think is not the case today. Prove otherwise please.

Also, the allowJS compiler switch became the preferred approach for in-place migrations over mass renames. It makes it easier to opt in to strict type checking on a file-by-file basis.


I very rarely see TypeScript developers actually use `any` (usually to reflect something like something parsed from arbitrary JSON that needs to be interrogated rather than just type-asserted) and in my experience it's a rare shop that doesn't use `strict` for everything to at least force it to be called out and checked in code review.

`undefined` and `null` seem conventionally used to mean different things amongst the TypeScript developers I know. `null` is typically used to denote something that is consciously known to be nonexistent; `undefined` is not rarely, in my experience, used at all except as a check against something coming in from untyped modules. I'm sure there are people who honor this more in the breach than the observance, but this is pretty consistent in my experience.

Personally, I've moved to TypeScript for most of my personal projects, away from both Ruby and C#, and it's fantastic. (Some things remain more appropriate for the JVM, typically Kotlin, but that's OK, too.)

> I very rarely see TypeScript developers actually use `any` (usually to reflect something like something parsed from arbitrary JSON that needs to be interrogated rather than just type-asserted)

Even that example usage of `any` should be less common, now. I think `unknown` (which is fairly new) is better there.

Is it? My impression is that `unknown` type doesn't solve that specific problem.

    const out: unknown = JSON.parse("{a: 1}");
    if (out && typeof out.a === 'number') console.log(out.a);
gives the error:

    [ts] Object is of type 'unknown'. [2571]

Pretty sure you’re missing a typeof check for ‘out’.

I'm pretty sure I'm not.

    const out: unknown = JSON.parse("{a: 1}");
    if (typeof out === 'object' && out && typeof out.a === 'number') {
gives the error:

    [ts] Property 'a' does not exist on type 'object'. [2339]
It's a completely unnecessary check, anyway: `out &&` is sufficient to exclude `null` and `undefined`, which is all that's needed to ensure that `out.a` won't crash. I challenge you to give a single input to `JSON.parse` that would crash my code without the `typeof` check.

I see what you mean. I guess unknown just doesn't work that well with inline type checks for objects, although in that case you probably want a function anyways. Using the `in` return type you can do something like this:

  const out: unknown = JSON.parse("{a: 1}");
  interface MyStructure {
      a: number;
  function isMyStructure(toCheck: unknown): toCheck is MyStructure {
      return toCheck instanceof Object && 'a' in toCheck;
  if (isMyStructure(out)) {
This will give you no type errors, and gives you the benefit of having a re-usable function for this validation. I just discovered this today. I seem to have missed it in a recent release note.

Oh, yeah, that feature's existed for years; it's called "user-defined type guards".


Unfortunately, it doesn't work in `checkJs` mode, and I always wish I could do it inline.

> I very rarely see TypeScript developers actually use `any`

I mostly use it to cheat when instantiating / using HoCs. Across various packages, they are rarely entirely correctly typed.

> But I will not recommend any other people (non-JS) to use TS at all

JavaScript, and increasingly in the Typescript flavor, is the language of the web. What real alternatives are there presently, that additionally gives a developer decent career opportunities?

TS vastly improves on JS in most aspects, while keeping a 100% compatibility with pure JS, i.e. you can just change the extension of a working .js file to .ts and instantly get access to the TS goodies.

You seem to complain about this compatibility, but a serious TS developer will not maintain such compatibility for long (will typically start restricting 'any' type, etc). This compatibility is the effect of the TS onboarding strategy, a crucial one at that.

The typeguards problem you mention is just one of the problems a JS/TS developer deals with as a matter of course, and will usually have solved by creating/using a utility library, something which JS notoriously requires, and something TS doesn't aspire to help you with, for the same above mentioned compatibility reasons.

> JavaScript, and increasingly in the Typescript flavor, is the language of the web. What real alternatives are there presently, that additionally gives a developer decent career opportunities?

As a Scala developer who realised the writing was on the wall for server-side rendering, I spent a good few months trying to use Typescript. It's decent, but the type system was still a huge step down from what I was used to.

A month or so ago I got around to trying Scala.js, and it was... nice, and oh so easy. Facades available for all the big-name javascript libraries. Write ordinary Scala code with the advanced type system and full IDE support that I was used to, and get the same ability to rule out huge classes of errors that I have on the server side.

So, Scala? It's controversial for many but it supports a lot of development styles, uses a runtime that already has a lot of enterprise backing (and will be able to interoperate with your existing libraries if you're a Java shop), and is also used for various bits of exciting newish technology (Kafka, Spark and the like). So it definitely has decent career opportunities.

>> but TS can still allow shitty code

No programming language can stop this. Your issue is with bad devs creating bad code.

>> Using the type 'any'.

Using 'any' is either for prototyping, truly dynamic data, or edge-case scenarios, but Typescript is still far better than having no types at all.

I moved our projects to ts in early 2013. Back then there where no strict null checks (imo main feature of any modern language) and typesystem was in infancy, but still it was totally worth it - our team could reason about code and nothing broke at runtime.

Now ts come long way. If your start any js project - start in on ts. And by god - enable full strict mode.

>* Using the type 'any'.

This is easily enforced in your tsconfig.json

Have a pointer to a sane default tsconfig.json people could build upon?

Just turning on the --strict flag gets you most of the checks you want in a clean codebase.


Here's what I use:

      "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "outDir": "../dist",
        "declaration": false,
        "strict": true,
        "resolveJsonModule": true,
        "noImplicitAny": true,
        "noImplicitThis": true,
        "noImplicitReturns": true,
        "noUnusedLocals": true,
        "jsx": "react",
        "lib": [
      "compileOnSave": false,
      "buildOnSave": false

Yeah but a decent tsc configuration is not default, so many people are still writing shitty typescript.

You are grasping at straws at this point. TypeScript is not the end all and be all of programming languages. It tweaks Javascript to be a little bit more sane, that's all. The kinds of people that seek out this sort of thing probably know whether or not to enable "any", and did so for their configurations. Either decision paves the way towards a cleaner future; those that started from zero and had "any" disabled on day 1, or those that are cleaning up a large codebase and are slowly making progress cleaning it up. TypeScript lets you be either person and lets you make your own decision.

It is clear to someone with even cursory knowledge of Javascript and TypeScript what options are available in this regard. Whatever the default is, people can probably make the right decision for their application. It's not hard and it's not hidden.

`"strict": true` is turned on by default when you run `tsc --init` and is recommended in every talk by everyone, including the TypeScript team... So I'm afraid the defaults are indeed sane and exactly what you want. I'm not sure much of what you've said in these threads really gels with reality so far.

For anyone confused: `"strict": true` in `tsconfig.json` just blanket enables all type checks, including future ones. You can then opt out of specific ones of your choosing if there's too much pain caused by the original authors, but none of those things are added by default. The TS team wants you to leave strict mode on.

To add to this, flow control analysis requires certain stict features. To be a bit obtuse; you want flow control analysis ergo you want strict :)

I find 'any' useful as a temporary placeholder for third-party data while I figure out what I've got. I wouldn't mind if linters throw errors at it, though.

In what little TS experience I have, third party dependencies that didn't yet have proper typings was the primary motivation for using any - and even then, you can provide a placeholder / temporary type definition for 3rd party libraries yourself. Which is an annoying chore, but you can't expect every JS library to invest time in adding TS / typing support because you would like it.

With that in mind though, a lot of JS libraries did add it, and the people running the @types repository did a lot of work on volunteering to add it even when the maintainers of the library didn't want it.

I like plain Javascript more. I guess those who are from Java/C# background would like TS.

> I guess those who are from Java/C# background would like TS

Been using dynamic languages almost entirely for the last 20 years. I love TypeScript. Starting to wish the other languages I worked with had optional types.

Good optional types that is. Python, my love of the last 15 years, is finally adopting optional typing but it's an atrociously bad system compared to typescript, to the point that I am seriously wondering if the language will ever have a decent typing system.

Having to import basic types, use awkward syntax, etc... Blergh. I really hope we can be more pragmatic and learn from typescript.

> Python ... I am seriously wondering if the language will ever have a decent typing system.

Considering that everyone seems to use six to target both Python 2 and 3, I am seriously wondering if the language will ever advance at all.

I don't think we'll get a Python 4 in the foreseeable future ([1] goes into more detail, from a core CPython developer's perspective). But that doesn't mean it can't advance, just that everything will be forwards compatible. Think C and C++, or even ECMAScript, for that matter.

[1]: https://opensource.com/life/14/9/why-python-4-wont-be-python...

Maybe the trick is being pragmatic all the way down and having a TS-like language (with Pythonic syntax) that's compiled to Python.

> Maybe the trick is being pragmatic all the way down and having a TS-like language (with Pythonic syntax) that's compiled to Python.

Mypy started out life as a separate language with pythonic but not Python-compatible syntax and multiple backends that was plannining to take advantage of static typing information and avoiding a GIL to be more performant than Python when compiled to native code rather than using the Python backend.

It later developed a Python-compatible syntax, before becoming a static typing front-end for Python.

Outside of JS land (and that only because of the browser being an environment where the only universally available thing is JS, though WebAssembly maturing may radically change this), there's not really a lot of demand for a separate language that fixes perceived warts in a target language but otherwise hews very close to the target and compiles to that target. Languages that aim to improve another languages ecosystem usually target the same VM instead of being transpiled, and usually offer different style syntax (e.g., Elixir for Erlang.)

I'm in the middle of upgrading javascript written by somebody who loves it to typescript. I definitely have a preference for strongly typed languages. It's not a crazy amount of work but I seem to be eliminating lots of dodgy code in the process.

There are whole categories of bugs that you can completely eliminate by simply annotating your code with some types. IMHO with the current state of technology, opting out of a static type system is getting pretty hard to defend. Why would you open yourself up to all the nasty bugs that can trivially be detected by a type system? How is that acceptable or better? Transpilers, type inference, linters decent editor integration, etc. have removed most of the traditional argumentation against this (e.g. verbosity, expressiveness, etc.).

Part of the reason is setting up the environment to run all these and the compilation overhead to see the result in browser. I would also like WebAssembly to really take off.

I like both, for their own merits. I personally believe TS is a better choice for larger projects with larger amounts of developers, for 'stricter' projects.

ATM I'm doing a pure JS project, it's just some React components / views and some functions that provide glue between 3rd party services. I might do a POC to see how easy it is to use in this project / setting.

I'm coming from a python/javascript background and absolutely love TS (and flow).

But both Flow and Jest are both developed by the Facebook team. First of all, like the author, I didn't say Flow is bad than TypeScript. Secondly, I moved from Flow to TypeScript last year. Anyway, this going to have a huge impact on Flow ecosystem.

FB devs show that there are no dogmas, only different solutions to different problems. Flow has its merits and was a good start as an experiment back then.

From last few months react community is embracing Typescript. create-react-app added support for typescript.

As a TypeScript Jest consumer can't complain, though @types/jest is pretty good.

I would be much more excited if they opened up Jest to be more "programmable" though. Dynamically creating tests and etc(before you ask, I was looking into wrapping an existing bash test framework in Jest). Perhaps the move to TS will make more of the internal interfaces feel public?

Something which I think could be helpful for the overall ecosystem, and allow both type systems to coexist and thrive, would be more attention put into tools which transpile code and type definitions between the two languages. The two most popular projects that I could find[1][2] are unfortunately incomplete and have not received any real updates in months.

[1] https://github.com/joarwilk/flowgen [2] https://github.com/bcherny/flow-to-typescript

This is awesome. Just yesterday I was asking around the TS community what good (opensource) CLI with plugins/extensions were there that were written in TS. I was looking for code I could use as learning and inspiration. I was led to vscode and angular-cli, which are both in github. Funny enough, they are also mentioned in this PR's comments.

Jest, once/if migrated will be another great addition. Hopefully that will happen soon. The community would really profit from great inspirational codebases (CLIs in my case) written in Typescript.

Vscode project is a beast with some pretty unintuitive module boundriea due to their platform separation and not bothering to export anything separately (like their IPC system)

Check out the CLI for TypeORM. It uses yargs which has pretty good types, and I have used it successfully a couple places now (internally). No plugins or extension examplea though last I looked :(

So how long until the best parts of TypeScript are subsumed into JavaScript, and TypeScript is discarded like CoffeeScript?

CoffeeScript and TypeScript are different enough that I don't think TypeScript could possibly have the same fate. CoffeeScript was all about syntax sugar, but 95% of the value of TypeScript is the typechecker that runs in your dev environment (editor, CI, etc) and has no business running in the browser. I sure hope we don't get to a world where every browser needs to implement a standards-compliant typechecker; that would be both architecturally questionable and greatly slow down improvements to the type system.

It would be nice if the browser could accept and execute TypeScript code (that is, ignore the type annotations), which would avoid the need for a transpile step, but that's a relatively minor improvement, and would certainly not be a replacement for TypeScript itself.

FWIW, “the browser” already type checks Javascript.

Where a compiler would throw an exception, the Javascript runtime creates/destroys optimizations.

For example, ‘1 + a’ type checks ‘a’ and optimizes the assembly if ‘a’ is a number. As soon as there is some other type represented by ‘a’ the runtime deoptimizes that method.

If the runtime could just throw an exception in those situations and keep the typed optimization a lot of our Javascript might run faster.

Browsers certainly collect runtime types of variables in hot code paths, but that's pretty different from the whole-program static verification that TypeScript does. TypeScript is designed to have an expressive and flexible type system, and typechecking a large codebase might take tens of seconds or minutes, not something you want running every time any user loads your site.

That said, including types in JS could be useful as a hint for the optimizer, but at least in TypeScript and Flow, the types can always be wrong even if no errors are reported (e.g. from misuse of escape hatches), so the runtime would need to double-check them.

I agree with you. They definitely should keep doing "type checking" lazily.

From what I understand, it would be a lot cheaper if types were built into the language, and the runtime's contract could trust the type and if it is wrong then undefined behavior occurs.

That would be a good day for everyone, but I don’t see that happening any time soon.

TypeScriot has a lot of features and the time to move those through standardization and then runtime (and browser) implementation is nontrivial.

If TS runs stalls and doesn’t innovate it _could_ happen, but like I say, subsiding all of those features into the base language would be a win for everyone.

I don't understand.

Why not Reason?

In addition to the "more approachable to contributors" answer, Flow and TypeScript are easy to port between, since they're both light extensions to JS and have almost the same syntax. I've done a Flow to TS port a few times and almost all of the code stays the same, it's just accounting for little differences in the type system details. Switching to a completely different programming language is much more work and much riskier.

This was discussed in the issue


“… so I’ll low-key passive-aggressively do it while pretending to comment”? :)

Look, Elm and Typescript are two very different things with different goals. There’s no problem developing a new app in Elm if it suits your use-case, but if you’re doing any number of other things - improving an existing app, writing a server app, working with Javascript developers - Typescript might be a more suitable choice.

From my point of view, I was able to slowly convert an existing large web app to Typescript over the course of a few months by rewriting a file whenever I touched it. Now the code is more reliable and easier to work on. That’s a good solution, but not one that would have been feasible with Elm.

You put out your opinion, another user puts out his opinion. If you think different opinions are harassment what are you doing on HN?

It's a large codebase that already uses Flow types, which has almost identical syntax to TypeScript, and its users are almost all JS or TS developers.

I think this was addressed directly when Reason was mentioned as a better option...

> @orta already answered here, but the tl;dr (at least to me) is that the point here is to make the code base more approachable to to new (and old) contributors who are consumers of Jest. The vast majority of them are JavaScript developers, not OCaml developers.

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