Hacker News new | past | comments | ask | show | jobs | submit login
TypeScript support added to Create React App (github.com)
280 points by mattwoodnyc 5 months ago | hide | past | web | favorite | 87 comments

offtopic, but I'm in the middle of trying to convince my small team to pick up typescript for a new significant node backend for our company. It seems like a no-brainer from my perspective. Compilation is fast, we would use `strict` but would allow devs to default to `any` if the types got too hard. There are no downsides but so many upsides - better refactoring, intellisense, documentation, communication of interfaces, protection against the javascript and library minefields. Glad to see there are lots of other people thinking this is valuable - wish I could figure out the right way to convince my team.

If you have influence over these kinds of decisions, then I expect have the experience to know that every choice has downsides.

If you haven't found any yet, that should be a Big Red Flag to you. It means you've let yourself get blinded by hype. The good news is that you're part of a team, and your team will probably be able to point some out to you.

Listen to them.

Once you've finally gotten yourself a sense of both the upsides and downsides, and have considered the latter seriously, work with your team to make a decision together. Then try to let yourself buy into whatever decision gets made!

There are definite benefits to TypeScript, but remember that no change comes for free!

I responded to someone else saying this, but I guess it bears repeating. I'm not saying its a free lunch - it is a build step - there are things to learn - some of the more esoteric types can be very hard to understand. I exaggerated when I said there was no downsides, what I mean to say is that in the cost benefit analysis as I see it so far, the benefits massively outweigh the costs. I've written a fair bit of TS so far and I find it hard to imagine writing a significant side code base without it in JS-land.

I'm not blinded by the hype, im here asking people for what they see as the downsides, the reasons they may have or have heard of why teams didn't pick TS (or better yet did and had some reason it didn't work out).

For what it's worth, your grandparent comment didn't ask any questions, particularly about potential downsides of migrating to TypeScript. Perhaps there is a different comment where you asjed such questions?

In any case, happy coding

There are _some_ downsides:

* Slightly more complex build workflows

* Integrating with non-TypeScript libraries can be difficult depending on the quality of external typings available

* Error messages can at times be slightly obtuse (especially depending upon the complexity of types used)

* Learning curve of TypeScript (Certain language features can be a bit complex. For example, mapped/conditional types might seem tough for a beginner. See here for an example[0])

That said, to me, it's still a no-brainer to use TypeScript for anything beyond the most trivial of apps. The advantages it gives you have heavily outweighed the disadvantages in my experience so far.

[0]: https://github.com/piotrwitek/utility-types/blob/532fe5cfcc5...

My favorite is [1]. The downstream errors that type generates are "fun."

"Slightly obtuse" is an understatement when dealing with `Pick` and the errors the complimenting mapped types generate. Once you throw in React and higher order components, you can get errors that are literally several console pages long - although that's usually just tsc "tracing" the error through the complex types.

[1] https://github.com/piotrwitek/utility-types/blob/532fe5cfcc5...

Yes, your experience mirrors mine completely. It's quite difficult to get complex higher-order components working correctly, especially if you're throwing in things like defaultProps and propTypes. For example, some issues I've hit recently: [0][1].

I think this is likely an artifact though of how powerful TS's type system is. I'm sure there're error-readability improvements possible, but with such complex type constructs, it's not all together surprising to me that the error messages can be difficult.

My worry with these challenges is not that they make TS unworthwhile (it's still completely worth it), but they do make it a little harder to convince a team to adapt TS and sell TS to React developers who are use to working in JS.

I know the TS team has React support as a priority and they've done a pretty great job of making TS React-friendly. I do wish they'd be slightly more hands on with maintaining `@types/react` and even publishing documentation, but perhaps it's fine to leave that to the community.

For those struggling with React typings, https://github.com/piotrwitek/react-redux-typescript-guide is my current favorite resource.

[0]: https://github.com/Microsoft/TypeScript/issues/27484 [1]: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/28...

I always found react-redux's connect function maddeningly hard to understand, because it does far too many things all in one function. The types just expose that complexity, and make it plainly obvious that it should be split apart.

The great thing about types is that the make you think more about keeping you APIs nice and clean on a semantic level, not just about if the syntax in your examples look pretty. I really hope more library authors use them early on so they avoid such mistakes in the future. There's only so much the Flow and TypeScript devs can do to make up for those existing problems.

Which gets to my wish that instead it is the React team themselves that adopt and maintain @types/react more directly, rather than leaving it to the community and/or Typescript devs. Seeing CRA add default support for Typescript transpilation with easy opt-in for type checking, is a great sign that plenty more React developers are going to have a chance at Typescript. Hopefully it becomes more of a two-way street where the Typescript community isn't just typing major React libraries after the fact, but more of the libraries are directly written in Typescript or at least the types are directly maintained by the authors of the APIs.

They have been working on the error UX for the last 2 releases and still have some things planned https://github.com/Microsoft/TypeScript/issues/26077

I recently updated our small node backend to Typescript and it's absolutely great to work with. Even backend people who come from strict languages Scala / Kotlin / Java, are now able to use and understand this.

I've been doing the same thing on our Angular app, but it has become clear that most of the frontend developers here lack the understanding on type safety, they're just unable to comprehend it for some reason. I've seen PRs that were just completely wrong because they couldn't understand how to do things correctly now that it's all typed. These are purely frontend people tho, they hardly work with any other language than JavaScript. But I don't consider Typescript a massive change from JavaScript, it just adds typing to it. Which any programmer should be able to comprehend.

Personally for me it has been great, it forced me to refactor really bad code, because I noticed that multiple methods kept returning different things, so the backend codebase is a lot cleaner now. Tests also have improved a lot because of all this.

Perhaps it might be worth trying to figure out how your team thinks about this, they might just be worried that they won't be able to work on it.

If people are not onboard with the the idea then it might be an uphill battle. There is value in TS but it will be frustrating at times, you will get resistance from other developers, and every once in awhile it will not feel worth it.

The other issue is that if people don't know what they are doing with TS, then imo it's worthless. I don't know your experience level with TS, but it is a non-trivial problem to build types such that it provides all the benefits you describe.

It is, in a lot of ways, a different language with its own set of problems to "solve."

Tread lightly, because adopting TS could be a blessing or a massive time sink for people not familiar with it.

I wouldnt call myself an expert by any means, and sure there are lots of complicated types out there - but I feel we would get 90% of the benefits if all we did was 1) turn on the compiler in the first place 2) document the argument and return types of functions and 3) build some general interfaces of objects we are passing around.

If we bailed out and typed anything more complicated as `any` it would still be a huge improvement over writing vanilla js IMO.

Yeah, there are so many crazy benefits just by naming your file `.ts` and writing vanilla JS. People can go as lightly or as deeply as they want once they understand how tsc works.

I had a similar discussion with some good points in this thread.


Who's in charge of making the decision to switch? What are his priorities? What problems is he trying to solve? How does switching to typescript help him do that better/faster/cheaper/easier?

Thats the problem, I dont really have answers to those questions about his priorities/motivations/reservations yet - just that there are some. Hope to find out soon.

The tradeoff between flexibility and reliability in the interface engineering world is very poorly understood. There's several dozen layers of reliability abstractions you can add to your Javascript code. Each one individually is probably a smart idea; taken together, you can create an endless array of overhead to even complex Javascript apps that massively reduce flexibility and slow down the iterative process if you want to continue improving and experimenting on your UI.

> There are no downsides but so many upsides

I've not used TS, but from what I've read the types from TS are not js compatible, so once you go into TS you have code that just isnt js.

(As opposed to flow, where you can just have it not be used)

While transpiling is normal, I'm as hesitant to tie myself to TS as I am to, say, a non-standard decorators syntax. Anyone coming to me with "there are no downsides" in such a case doesnt sound very credible.

Assuming I'm wrong, how would you address this?

I'm not sure what you mean by "not JS compatible" here.

TypeScript obviously compiles into JavaScript, and any valid JavaScript is also "valid" compilable TypeScript (the compiler will complain, but it will still compile it into JavaScript that does the same thing). With the right assertions (and @ts-ignore where necessary), you can even get the compiler to stop complaining!

TypeScript does have some differences beyond just type annotations: namespaces and enums come to mind. But it's easy enough to just not to use those features - they're not even supported by Babel.

The main downside is that you have a compile step where you might not have had one before. And it can be frustrating to deal with situations where there's no way to "fix" an error except by suppressing it – but these are really rare. But these are relatively minor issues.

Also, even namespaces and enums aren't that foreign, and are still "JS compatible" in that they transpile to perfectly normal JS code that you can still use quite obviously in other JS code (enums create a list of constants and sometimes a reverse lookup map; namespaces create ugly, nested, mergeable object literals and IIFEs just like Grandma jQuery used to bake back in the bad old days before module systems). From one point of view they are nothing but syntactic sugar for common JS patterns.

There is a significant difference between TS and a non-standard anything. Nothing goes into typescript until it is stage 3, meaning intent to ship. There is now two compilers supporting the syntax. It is well supported.

Also, if that was a concern I would be willing to say we start out with jsdoc style types - I would much prefer the regular syntax and would like to use things like enums, but it would be a massive improvement over not having it.

In my mind, you are writing javascript with types whether you use typescript or not - using TS makes those types explicit and allow a compiler to check your work, on top of the other benefits.

I will rephrase though - instead of "there are no downsides" I'll say "Any downsides I have found are minute in comparison to the benefits", but my intent behind bringing this up in the first place is to hear from anyone else who does see more downsides than I do and to understand those.

You're wrong.

Once you transpile the TS, you have standardized ECMAScript. Want to stop using TS? No problem. Just delete your TS files and work from your JS files.

And, beyond that, TS is intended to be a superset -- never incompatible, just "extra".

Finally, you can use TypeScript the same way Flow is used, through comments.

Tying yourself to TS isn't really something you can do, and there's zero risk in using it. You can always throw it out later.

> No problem. Just delete your TS files and work from your JS files.

This is quite an irresponsible comment.

The JS code generated isn't really meant for editing especially if you used a feature that isn't present on the runtime (like async/await in browser), not to mention all the formatting is rearranged.

If you're willing to go back to JS, you want to keep the original source.

"Irresponsible" is a bit of an overstatement, don't you think? The TS team explicitly says their goal is to generate readable JS, unlike (for example) Clojure or Scala.

Also, the async/await thing isn't an issue if you target the latest ECMAScript version. That's the only really ugly thing, and it's been easily avoidable for over a year.

Readable JS doesn't mean, convert back to the file in the format you used to for editing.

That comment could make people throw away the original and end up with machine generated code when going back.

Have you read transpiled TS before? It's sometimes almost identical to the source. It's as close as you can get to just removing the static typing. Variables have the same names, for example.

I used to have a problem where I'd be debugging the JS instead of TS file because visually, they were almost identical.

Have you seen the code the TS compiler spits out?

You do not want to work on that. It readable to an extent, but it's definitely not pleasant.

I don't think you could just go back.

If you're referring to generator-style async/await, you can change that now.

Otherwise you can just prettify it and be on your way.

Sure you don't want to go back, but that's the whole reason TS exists: writing JS with good organization and discipline is impossible at worst, full of boilerplate at best.

TypeScript and Flow are very similar. Compilation of both of them mainly consists of removing type annotations. TypeScript has a few extra things it adds but they're very minor and not that hard to translate into Javascript.

I had the advantage of working with people who had a background in typed languages, so everyone was onboard with giving Typescript a try a year ago.

The thing is, I found you have to be very diligent about how you organize your interfaces and how you might namespace them. I had some C# background, and had made a PR or two to the vscode repo -- so I had an idea of "good" code.

I think without some background in how you'll organize you types and, most importantly, types themselves you'll have some legwork in proving Typescript useful.


A suggestion I might have, because I found this mentally pleasing: start your project off small (get a few endpoints and some minimal database interaction). Let your co-workers look over it / maybe even do some small amount of work.

Create a typescript branch, where you convert each file to `.ts`. Typescript's compiler `tsc` can copy over all files `.js` and converted `.ts` so it's not essential you do this all at once, but I also found it not-so-painful either.

Demo this branch and show your co-workers that Typescript provides:

- A nice boost in productivity (autocomplete, hurray)

- Some confidence in how you're using types (this isn't a sound type system like flow)

- A way for people who don't have a background in javascript to feel more comfortable

Does it add value? I manage enterprise and we’ve tested typescript and found it added little value, but brought in complexity that slowed production.

Type safety isn’t worth having more complex prototypes, and having to keep up with both JS and Tyoescript, for us.

It’s very easy and forgiving to do a proof of concept though, because it integrates so easily into your existing code base.

Just be sure it actually adds real value and isn’t something you do for hype.

I’d certainly utilise it if we were building something as complex as VSC, but we aren’t, and I think it’s important to keep in mind that typescript isn’t all positive gains but that it also has downsides.

Not sure why you're downvoted but for me vanilla JS is like cars running without traffic lights, you know it when you crash but with TS, chance of doing something wrong, like parameters have wrong key or type, before it runs gets less especially under multiple devs.

And then, you can code with TS on the server side as well as take that approach and write with modern language features on the browser side where you still have to write in ES5 (IE11) if it isn't for transpilation and develop with 1 consistent language throughout.

Out of curiosity, how do you let everyone take the build process in a consistent way?

I've only used TS as a single dev but with multiple editors and they could have different version of TS from the other, I wonder what's the best way. Do you just help a guy with vim/vs code/IntelliJ/sublime/etc to set up to use auto TS compile and ask everyone to stick with a specific TS version? Or is it better to use something like Prepros to handle all the builds?

We have the entire development environment in Kubernetes. IDE is only used for code editing, which is then synced to the cluster. Auto-generated code and node_modules are synced back for code completion.

That way, everyone has an identical dev environment and we don't depend on any particular IDE (want to use Emacs? sure). No setup steps, just running one script to create a new namespace with all applications running inside. Broke it, messed up an upgrade? Just destroy and redeploy.

We hacked Arcanist[1] to run linters in the cluster. Modified a TypeScript file? "arc lint" will make sure your TypeScript pod is up-to-date and run the linter there, etc.

We're using custom tooling which is faster than https://github.com/GoogleContainerTools/skaffold, but it's the same approach.

Thinking about open sourcing it.

[1]: Phabricator's CLI client

Having the build on server side seems like the way when you don't have to ask each dev to set stuff up and it will be a hassle to change environment once deployed. I also auto upload my TS to server and let the server handle it but I do wonder if there's an easy way for average shops to deploy.

It seems everyone is doing their own way of build process from local build, gulp, webpack or custom server processing and all has their downsides.

It does seem like a hurdle when this process isn't easy for everyone involved when switching to TS.

usually you try to stick to the Typescript version defined in dependencies. In VSCode for example you can easily switch Typescript from editor version to project dependencies version. And most of the time what we do where I work is only triggering `tsc` commands (or any other dependency command) through NPM scripts, because they use the dependency installed locally instead of any other globally installed or editor specific version.

TypeScript supports Flow-like type annotation in comments, which allows you to take advantage of static type-checking without transpiling.

That's as much as I know about it. I don't use that feature because transpiling is such a minor issue that I can't imagine any universe in which I would use comment-style types, which are slightly more cumbersome to use.

That feature is for JS files. It helps you convert your JS project into flow/TS in a piecewise manner. Otherwise you'll have to do a major rewrite in a very short amount of time.

> Otherwise you'll have to do a major rewrite in a very short amount of time.

This just isn't true. TS was designed from the beginning to allow gradually adding types. Whether transpiling or using comments, you can change one file at a time.

Indeed -- interop works _very_ well.

Strange: you're trying to convince someone, but instead of writing about their thinking and their arguments, you're writing about yours. If you want to convince another human being, shouldn't you focus on their mental picture of the problem more than on your own?

why not just ask how they feel about it and try to address concerns if they come up?

That will certainly happen - my intent behind this comment is to hear from other people who have looked at it and decided against it. Or devils advocates - I'd like to hear anyones reservations either to convince me its not as good as I think it is, or at least allow me to come up with a response.

Interesting that the first line of that pull request removed the Oxford comma.

I'm pretty sure it wan't intended at first place though.


Please don't post unsubstantive comments here.

This is awesome. I recently moved from Typescript to plain Javascript for a project and it is quite frustrating.

You don't realise what you had till it's gone!

For someone stubborn that refuse to use TS, what are you missing ? Is it the IDE tools or the compiler error messages, or writing type annotations ?

In addition to icholy's points, stronger typing means one traps a whole class of errors at compile/build time, as opposed to runtime.

IDE tools, compiler error messages, self documenting code.


What a scary thought... leaving TS and going back to JS.

BTW, anyone here used ReastReason, BuckleScript is it? I've been meaning to look into it but don't have a sense of the payoff. I read that it can coexist which is a great feature. Wonder how it compares to a TypeScript workflow.

As much as I want to love it, I’ve found it far too restrictive, which makes it difficult to play around with and learn (although error messages have recently improved).

And while I like that JSX is built-in, I don’t like that it’s so different. And having to use <div> ReasonReact.stringToElement("Blah") </div> (The spaces are required) everywhere instead of <div>Blah<div> makes it feel like a poor imitation of JSX and isn’t fun at all. But maybe they’ve fixed some of that.

Someone else said Reason is “better”. The type system might be more sound but TS is far more flexible and forgiving, and doesn’t have ugly and off-putting syntax for promises/async and interop.

I find the benefits outweigh those disadvantages, but I would never suggest switching to Reason for a non-experimental project at work because I think the disadvantages scream “this isn’t quite ready yet.”

Yeah, I'm looking forward to syntactic sugar for JSX strings and async/await.

Error messages could be better, Elm has set the bar in that regard.

Types are inferred, i only had to write a type once to disambiguate. Fearless Refactoring. If it compiles it works, except if you built in some logic errors. The compiler will find all syntactic and type errors, which might feel annoying at first but if you reframe it into the compiler is helping you then it is fine.

Much faster compilation times, very strick static type checking, however a very small community. Interop syntax is pretty tedious but it has no performance penalty. For example Clojurescript has a much bigger community.

If you find yourself using ImmutableJS, Ramda, Recompose, etc. in your React project, you should have a look at ReasonReact. It felt like a breath of fresh air to me.

I'm diving into Reason now and it seems great. It seems like "Flow done right" -- about a year ago, I did a study of both Flow and TypeScript, then picked Flow because it seemed more principled and expressive. But it turned out that bolting Flow onto Javascript left it with a lot of edge cases and some oddities, but Reason instead avoids that by compiling to javascript instead of being bolted atop Javascript.

tldr: Reason is better than both TypeScript and Flow and has equally good interop with native untyped Javascript code.

Pretty much just file extension support and docs. The support mainly comes from Babel 7.

I'd call that a good thing, really. Not needing ever more dependencies.

I think this is a solid direction to go.

Let's just say I give the React devs... props.

Funny, cause just using typescript to compile means you get to drop a lot of Babel dependencies / eslint dependencies.

There's still react-scripts-ts [1] which drops the majority of Babel in the CRA pipeline for solely Typescript. Presumably, it will remain active as it is still a useful alternative if you know you are going to want Typescript from day one. (This Babel-based support is perfect for those unsure and looking to experiment, which is great.)

[1] https://github.com/wmonk/create-react-app-typescript

I use react-scripts-ts. There's an open issue discussing the future of it now that CRA does it on its own.


create-react-app is built on Webpack, for hot module replacement (HMR), and that requires a webpack loader. There's babel-loader and ts-loader. The stats in the projects are similar, but babel-loader is part of the babel project while ts-loader comes from an independent project, so it may be better integrated. Also ts-loader suggests using it with babel-loader. I'm not sure why, but if you install ts-loader and babel-loader you'll wind up with more dependencies than if you just install babel-loader. https://github.com/babel/babel-loader https://github.com/TypeStrong/ts-loader

The last I checked (a month or so ago, but before the recent 2.0 release) create-react-app didn’t have hit module replacement. It just watched files and completely reloaded the browser when anything changed.

How well does Babel transpile TS? My initial instinct is that I'd trust the real TS compiler over Babel, but I've never tried compiling TS with Babel.

I assume the real TypeScript compiler still does the type-checking and that would be unaffected by Babel.

The TS team implemented the TS parsing support in Babel. You are correct that the TS compiler is still needed for the typechecker, however.

Ah, I didn't realize this, very cool collaboration! For those who are reading this and might find it helpful, here's a link to the official blog post on the work: https://blogs.msdn.microsoft.com/typescript/2018/08/27/types...

We added more changes on master, now it creates tsconfig automatically, checks if the required dependencies are installed and other nice ux improvements.

I'd love to use TypeScript, but I've hit walls of errors that are nearly as bad as the old C++ template errors! (Though to be fair, this was a while ago, the compiler may have improved).

SO: Any good way to learn TypeScript, particularly the more complicated types?

What sort of errors are you running into, and what project setup are you using?

If you're using Create-React-App-TS, that's a separate fork of CRA 1.x that adds TS support, and has _horribly_ restrictive lint rules (many common style practices are treated as _compile_ errors). See https://github.com/wmonk/create-react-app-typescript/issues/... for discussion. (I ran across this while trying to set up a TS project for another team.)

I'm happy to see the TS support in CRA 2.x, because now I can actually recommend that people use it to get started with TS support.

I personally had never actually _used_ TS at all until this last week, when I was helping that same team rework some of their code. They'd been slapping `someVar : any` across the entire codebase just to make the compiler shut up. I tried adding a type representing their API response object, added it as a prop to the appropriate React component, and showed them how you could start getting autocomplete and compile-time catching of mistakes, and suddenly they began to see that there were actually benefits of using TS, not just overhead. I'm hoping to try adding TS support in to my own team's codebase in the near future.

I use TypeScript every day, and I like it way better than JavaScript, but here is an example of a bad error message: http://ss.nican.net/photo_2018-10-22_22-09-58.jpg

Yup, totally agree - that's pretty tough to read.

In that _specific_ example, I think the key part is the "... is not assignable to ServerRoute | ServerRoute[]". It's just giving you all the fields in the type of the object you _are_ returning, and trying to tell you "I can't go from an A to a B". But yes, hard to pick out the key bits of info in there.

Thanks! I'll give it a go... I was trying with CRA, with the older compiler.

Have you used TypeScript 3.0? They improved the type errors a lot. I'd highly recommend giving it another shot.

That was one of the advertised major features for 3.0 and I really like TS, but I haven't noticed a difference.

Still getting frustratingly long and nested error messages that are impossible to read within a tooltip or error pane of vscode. More often than not I just missed or misspelled a single property off an object, but the best source of information for that ctrl+space to see what the non-optional properties are with autocomplete.

Maybe I'm spoilt from what I've seen in Rust and Elm, but either the error messages are useless or I need to copy and paste the tooltip contents into another editor window to spend 5 minutes to decipher them.

It could be that I'm just dealing with complex types with the various libraries I'm using, and so there isn't much TS can do. Some of the React types do seem to get complicated.

One trick I use: start from the bottom of the wall of error messages. Often the root cause of the problem will indicated there.

Quick q, are the "walls of errors" of errors coming from code you wrote yourself or from 3rd party libraries?

I ask because you say that you want to learn the more complicated types, but I'd say it is better to stick to the basic types for your own code.

It seems obvious to me now, but It took me a while to realize: the reason TS type system is so advanced is to be able to accommodate all the crazy JavaScript APIs that are already out there in the real world. New code doesn't need (and most likely should not) use many of those complicated patterns.

This is also why other compile-to-JS languages have an advantage over TS: they don't have the burden of having to express all the craziness that is JS, and will probably be built around a much simpler/cohesive core of ideas.

TS is still an amazing compiler that provides lots of value: many projects other than TS benefit from TS type definitions. But I'd rather use something else if I'm writing an app from scratch. I'm exploring ClojureScript these days.

Great to see. Any javascript project of reasonable size quickly eventually collapses under its own weight.

Typescript looks interesting and increasingly appealing -- it is high on my list of tech to explore.

However, absolutist statements are not very useful... It shouldn't even need saying, but clearly large javascript projects do succeed from time to time.

"Time to time" is reductive even. Large Javascript projects succeed all the time, and have done for decades. This whole thread needs a bit of perspective, no matter what you think of Typescript, the web wasn't invented in 2015...

Very true. I was being soft with my language in an effort to make my point more digestible.

I guess it depends on your definition of large...

Applications are open for YC Summer 2019

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