Skip to content
This repository was archived by the owner on Aug 5, 2021. It is now read-only.

Commit 61836f8

Browse files
committed
rewrite with language service in mind
1 parent 904cd9a commit 61836f8

File tree

3 files changed

+92
-83
lines changed

3 files changed

+92
-83
lines changed

README.md

100644100755
+91-82
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,30 @@
1-
# Closing the loop: why TypeScript and React are a superheroic dynamic duo
2-
3-
or, the joy of tool-assisted typesafe frontend web development
4-
5-
or, why types and the
6-
[language service](https://github.com/Microsoft/vscode-html-languageservice)
7-
are superheroes of frontend web development
8-
9-
10-
### ***Important update!!!* this post is *already outdated* and full of FUD and falsehoods
11-
> I unknowingly spread lies and FUD in this article comparing the capabilities
12-
> of React to Angular, Vue, Ember, and other string-based templating frameworks.
13-
> I'm sorry. Seriously. Posted to reddit and everything.
14-
> **Nothing described here is specific to React.**
15-
> I failed to anticipate that Angular and other frameworks could theoretically parse
16-
> their string templates and integrate with a typed language like TypeScript,
17-
> and get all of the tooling benefits that React enjoys.
18-
> This very thing was [released](https://blogs.msdn.microsoft.com/typescript/2017/04/27/announcing-typescript-2-3/)
19-
> the day after I originally published.
20-
> This invalidates this article's comparison of React to Angular, Vue, and others via its new
21-
> [language service plugin API](https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API).
22-
> Here's a [great talk](https://www.youtube.com/watch?v=ez3R0Gi4z5A).
23-
> I'm going to post a [followup](https://github.com/ryanatkn/language-service-in-motion)
24-
> to this article with some snappy Angular animations,
25-
> and maybe more - [GraphQL](https://github.com/Quramy/ts-graphql-plugin)? Yes please.
26-
> Below is a somewhat edited version of the original -
27-
> ~~strikethrough text~~ is used to preserve mistakes and is followed by a correction.
28-
29-
> I may just keep this repo as is, as a monument to my ignorance.
30-
> [Here's the followup](https://github.com/ryanatkn/language-service-in-motion) -
31-
> a new repo that encourages everyone to submit
32-
> animations that demonstrate the
33-
> [language service](https://github.com/Microsoft/TypeScript/wiki/Architectural-Overview)
34-
> in motion for any library/framework/language/editor.
1+
# Closing the loop
2+
### types + language service = awesome frontend webdev
3+
4+
> In the original version of this article, I mistakenly praised the capabilities
5+
> of React compared to Angular, Vue.js, Ember, and other non-JS-based templating frameworks.
6+
> As it turns out, tools don't care whether you put
7+
> your code in your templates or the other way around.
8+
> The day after I published this,
9+
> [TypeScript 2.3 announced](https://blogs.msdn.microsoft.com/typescript/2017/04/27/announcing-typescript-2-3/)
10+
> the stable release of the
11+
> [language service plugin API](https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API),
12+
> which allows other frameworks to get similar TypeScript tooling benefits that React enjoys.
13+
> I was wrong to say React was unique in this way,
14+
> and almost perfectly mistimed my post, and I'm sorry if I misled you.
15+
> Here's a [great talk](https://www.youtube.com/watch?v=ez3R0Gi4z5A) explaining
16+
> how Angular leverages types and the language service.
17+
> This article has been updated to clarify that React
18+
> enjoys no special ability to take advantage of type information.
3519
3620
React and TypeScript are well-hyped fixtures of the 2017 webscape,
3721
but not much attention has been given to how wonderfully they complement each other.
38-
This article and attached code demonstrate why I prefer
39-
building my views with TypeScript in React
40-
over the templating strategies used by other popular view libraries.
41-
42-
> tldr: React builds DOM and listens to it in a way that can be typechecked.
43-
> This simple fact provides substantial benefits over alternatives that use string templates.
44-
> Read on for more discussion and visual demonstrations.
45-
> This is the joy of tool-assisted typesafe frontend web development:
46-
>
47-
> `great web libraries/frameworks/typed languages -> great editor integration -> much productivity/happy`
22+
This article and attached code demonstrate what's possible
23+
in your editor when your code is fully typechecked on the frontend.
24+
React views are written in either JavaScript or JSX, which is also just JavaScript,
25+
so React can take advantage of types without special tooling,
26+
but the TypeScript language service allows other frameworks
27+
like Angular and Vue.js to enjoy similar benefits.
4828

4929
What follows is a whole lot of words that explain
5030
what "the loop" is and why we want it to be "closed",
@@ -54,9 +34,9 @@ Feel free to skip down to the pretty pictures.
5434
## What is "the loop?"
5535
React has promoted a now well-known concept called *unidirectional data flow*,
5636
which has been adopted by Angular 2, Ember 2, the React community via Flux and Redux,
57-
the Vue community via Vuex, and many others.
37+
the Vue.js community via Vuex, and many others.
5838
This contrasts with the *bidirectional data flow* or *two-way data binding*
59-
used in Angular 1, Ember 1, Vue 1, and Knockout, among others.
39+
used in Angular 1, Ember 1, Vue.js 1, and Knockout, among others.
6040

6141
There are a lot of
6242
[great resources](https://staltz.com/unidirectional-user-interface-architectures.html)
@@ -75,17 +55,20 @@ There's more to it, but this is the basic loop:
7555

7656
## What is a "closed" loop?
7757
At each step of the loop, we process data sent by the previous step.
78-
In JavaScript, the correctness of passing and processing data can only be tested at runtime,
79-
and static analysis has tight limits.
58+
In JavaScript, code that passes and processes data can only be tested at runtime,
59+
and static analysis has tight and fuzzy limits.
8060
In contrast, TypeScript and other typed languages are able to check more of the validity
8161
of each step at *compile* time because of the additional information provided by types.
8262
For the purposes of this article, I'm going to refer to a fully typechecked loop as *closed* -
83-
meaning *all* type errors will be caught by the compiler *throughout the loop*.
63+
meaning *all* type errors will be caught by the compiler *throughout the loop*,
64+
for some handwavy definition of "type error".
8465

8566
> My apologies if the term "closed loop" irks you or makes no sense -
8667
> please submit an issue with suggestions!
8768
> I felt that existing terminology doesn't capture the importance of this concept
8869
> in the context of single page web apps.
70+
> Also a caveat: nothing here should be considered valid computer science.
71+
> Some words with domain-specific meaning may get muddled ahead.
8972
9073
The benefits of having a fully typechecked *closed loop*
9174
go far beyond disambiguating strings and numbers.
@@ -105,6 +88,8 @@ In a closed loop, the compiler has your back - all of it.
10588
> and some things require type annotations that should be unnecessary -
10689
> the point of this article still stands.
10790
> Don't let perfect be the enemy of good, let alone great!
91+
> I'm sure future tooling will make all of this appear quite barbaric,
92+
> but it's a major improvement over webdev circa 2012.
10893
> Be sure to check out TypeScript's optional compiler flags that increase type strictness,
10994
> like `noImplicitAny` and `strictNullChecks`.
11095
> The experienced TypeScript developer will likely find and prefer
@@ -117,7 +102,9 @@ Error checking is only one part of the story.
117102
Types also provide the computer with a significantly improved understanding of your code.
118103
This empowers the computer to do far more than check for errors -
119104
from code navigation, to inspecting where and how which symbols get used,
120-
to making automated transformations and refactorings, there's so much the computer can do for us.
105+
to making automated transformations and refactorings,
106+
there's so much the computer can do for us,
107+
which for me translates directly into productivity and happiness.
121108

122109
Sounds pretty good right?
123110
The caveat is that the loop needs to be *closed* to provide a great experience.
@@ -131,6 +118,7 @@ update the variable name without the computer's assurances of validity.
131118
This is tedious and error prone - consider renaming a property named `text` in a huge app!
132119
If there can always be leaks and misses, you have to check everything manually,
133120
and fearless refactoring flies out the window.
121+
Worse still, your ability to understand the codebase shrinks as your app and team grow.
134122
A closed loop enables higher productivity for reading code, writing code,
135123
and maintaining and improving code quality over time,
136124
which leads to happier developers, happier users, and better software.
@@ -151,49 +139,65 @@ which leads to happier developers, happier users, and better software.
151139
So a closed loop sounds great - how do we get one?
152140
It turns out that the *view* is where most loops get broken
153141
in the single page web apps of 2017.
154-
This is where React differs from most other popular view libraries and frameworks.
142+
Err, well, that was true until Microsoft introduced the
143+
[language service](https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API),
144+
enabling deep integration between a typed host language,
145+
the code inside templates, and your editor.
146+
147+
Authoring views is where React differs from most other popular libraries and frameworks.
155148
If you can build your views with a typed flavor of JavaScript, like TypeScript,
156-
you can close that part of the loop! That's what React offers.
157-
Most view libraries do not allow building views with JavaScript,
158-
and even though some libraries like Vue offer this
159-
as an alternative to string templates,
160-
they still miss critical aspects of type safety, and the vast majority
161-
of the code in those communities has zero type safety in templates.
162-
Let's look at some popular frameworks and their loops with TypeScript.
149+
you can close the parts of the loop that connect with the views
150+
without a framework-specific language service,
151+
and this is where React has a head-start.
152+
Let's look at some popular frameworks that use
153+
string-based templating and their loops.
154+
155+
The following diagrams **do not necessarily imply shortcomings**
156+
of the frameworks relative to React -
157+
they were originally falsely diminishing in the first version of this article,
158+
but I think they still show how helpful type information
159+
can be in single page apps.
163160

164161
> `--->` is a fully typechecked closed step and `-/->` is a step
165162
> that breaks the loop by losing type information
166163
167-
Angular 2+, Vue, and Ember have ~~two~~ actually zero broken steps in the loop.
168-
To see what this actually means in practice, ~~skip down to the last of the images below~~
169-
check out the [Vue](https://github.com/octref/vetur/) and
170-
[Angular](https://github.com/angular/vscode-ng-language-service)
171-
VSCode plugins.
172-
164+
Without integrating with a language service,
165+
Angular 2+, Vue.js, and Ember have two broken steps in the loop.
166+
Here are the VSCode plugins for
167+
[Angular](https://github.com/angular/vscode-ng-language-service),
168+
[Vue.js](https://github.com/octref/vetur/),
169+
and [Ember](https://github.com/emberwatch/vscode-ember).
173170
```
174171
state -/-> view -/-> user input ---> business logic ---> state
175172
```
176173

177-
Cycle gets closer, but it prefers CSS selector strings for attaching user input handlers to the view:
174+
Cycle.js gets closer, but it prefers CSS selector strings
175+
for attaching user input handlers to the view.
176+
I don't doubt that some clever tools could staticly
177+
analyze the relationships between views and input handlers,
178+
but they don't appear to exist today.
178179
```
179180
state ---> view -/-> user input ---> business logic ---> state
180181
```
181182

182-
React is a closed loop - no broken steps!
183+
React is a closed loop by default, and doesn't need special tooling
184+
to integrate with the language service - there are no broken steps!
185+
This is a major reason why it has been adopted
186+
by users of typed languages like PureScript and Reason/OCaml.
183187
```
184188
state ---> view ---> user input ---> business logic ---> state
185189
```
186190

187191
Elm, PureScript, and some other languages with advanced type systems
188192
are able to get closer to a 100% fully typechecked closed loop than TypeScript can today,
189193
but they come with significant added friction to interoperating with the JavaScript ecosystem.
190-
This is not a tradeoff I'm willing to to make for most large applications.
194+
This is not a tradeoff I'm willing to to make for most large applications, but YMMV.
191195

192196
Enough telling - seeing is believing!
193197

194198
## Developing with a closed loop
195199
The following images demonstrate things that are
196-
only possible with a good type system and/or a partially/fully closed loop,
200+
only possible with a partially or fully closed loop
197201
and good editor integration.
198202
To try these things yourself, clone this repo,
199203
fire up your favorite editor with TypeScript integration
@@ -218,28 +222,28 @@ and start moving fast without breaking things!
218222
### Find all references
219223
![Find all references](/img/find-all-references.gif?raw=true)
220224

221-
### Angular's formerly broken loop
222-
~~In Angular, notice how the computer
223-
doesn't help with simple typos on the component or template,
224-
despite having first-class integration with TypeScript.
225-
None of the above demos work with Angular templates.~~
226-
Stay tuned.
225+
### Angular's language service integration
226+
It's not currently as complete as the React+TypeScript experience,
227+
but Angular has partial language service integration directly in HTML files,
228+
linking types between templates and components.
229+
I don't see any reason why it won't be as good as React's with more time.
227230
![Angular 2](/img/angular.gif?raw=true)
228231

229232

230233
## Conclusion
231-
Though imperfect, the TypeScript and React duo
232-
provide a wonderful development experience, relative to most alternatives.
234+
Types make working with frontend code a breeze,
235+
once you have good editor integration.
236+
Today's tools only scratch the surface of what's possible..
237+
238+
Though imperfect, TypeScript provides a wonderful development experience, relative to most alternatives.
233239
My hope is that more languages, libraries, and frameworks take seriously the idea that
234240
we can and should be able to *close the loop*, because a fully typechecked app is a happy app.
235-
We all need heroes - not to worship, but for their leadership -
236-
and today, for front end web development, React and TypeScript are two of mine.
237241

238242

239243
## Additional notes
240-
Can you do all of this with Flow, the Facebook equivalent of TypeScript?
244+
Can you do all of this with Flow, the Facebook competitor to TypeScript?
241245
Maybe! I don't know.
242-
The last time I evaluated Flow was over a year ago,
246+
The last time I evaluated Flow was years ago, *(edit: see update below)*
243247
and though it has some useful type features that TypeScript doesn't
244248
(like [$diff](https://flow.org/en/docs/types/utilities/)...yet?),
245249
the overall development experience, especially editor support and community type definitions,
@@ -250,6 +254,11 @@ to TypeScript, like `strictNullChecks`.
250254
If you're already transpiling your JavaScript, like with Babel,
251255
it's a modest additional cost to adopt a gradual typing technology like TypeScript or Flow.
252256
Hopefully I've convinced you to try a typed language that compiles to JS if you haven't already!
257+
**update:** I used Flow for a couple weeks in mid-2017, and I found
258+
the overall experience to be much less helpful and complete than TypeScript's.
259+
It has a theoretically more robust type system (see "soundness")
260+
but my experience tells me that TypeScript's leaning towards practicality,
261+
along with its maturity and popularity, make it a far better choice for me right now.
253262

254263
This article is from a programmer's perspective -
255264
designers and others may have different priorities.
@@ -266,8 +275,8 @@ can help us accomplish our goals with the right tools.
266275
Are React and TypeScript flawless? Oh heck no! Are any big software projects?
267276
But in my opinion, relative to other solutions,
268277
they're good - and together, for building UIs, they're *great*.
269-
The future may hold something even better.
270-
I'm watching WebAssembly eagerly, and I think BuckleScript+Ocaml/Reason have a shot
278+
The future will surely bring more evolution and new tools.
279+
I'm watching WebAssembly eagerly, and I think BuckleScript+OCaml/Reason have a shot
271280
at winning a lot of developers from TypeScript/Flow in the next year or two.
272281
Elm and PureScript are also interesting alternatives.
273282

img/angular.gif

-371 KB
Loading

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-typescript-closing-the-loop",
3-
"version": "1.0.0",
3+
"version": "2.0.0",
44
"description": "Closing the loop: why TypeScript and React are a superheroic dynamic duo",
55
"author": "Ryan Atkinson <[email protected]>",
66
"license": "MIT",

0 commit comments

Comments
 (0)