{"id":823,"date":"2018-11-10T17:49:24","date_gmt":"2018-11-10T17:49:24","guid":{"rendered":"https:\/\/www.crccheck.com\/blog\/?p=823"},"modified":"2018-11-10T18:25:05","modified_gmt":"2018-11-10T18:25:05","slug":"flow-type-coding-in-javascript-with-guardrails","status":"publish","type":"post","link":"https:\/\/www.crccheck.com\/blog\/flow-type-coding-in-javascript-with-guardrails\/","title":{"rendered":"Flow Type for coding in JavaScript with guardrails"},"content":{"rendered":"<h2 id=\"FlowType-Gettingstarted\">Getting started<\/h2>\n<p>Getting fast feedback in your IDE is vital to having a happy developer experience. Flow adds that value for me for JavaScript programming.<\/p>\n<h3 id=\"FlowType-Atom\">Atom<\/h3>\n<p>Install <a href=\"https:\/\/github.com\/flowtype\/ide-flowtype\">ide-flowtype<\/a>. I just switched from the lighter-weight <a href=\"https:\/\/github.com\/AtomLinter\/linter-flow\">linter-flow<\/a> and I&#8217;m liking it.<\/p>\n<h2 id=\"FlowType-Thegoodparts\">The good parts<\/h2>\n<ul>\n<li>You can use Flow with no transpilation<\/li>\n<li>You can use Flow with no transpilation<\/li>\n<li>The documentation it provides is very helpful. It&#8217;s more rigorous than JSDoc, but less human friendly because there&#8217;s no description. You&#8217;ll need an old fashioned comment (JSDoc?) for that.<\/li>\n<li>Speeds dev time. The fast feedback, jump to definition, and documentation makes it easier to do work (guardrails)\n<ul>\n<li>Even with weak mode and lazy annotations (just using <a href=\"https:\/\/flow.org\/en\/docs\/types\/primitives\/\">primitive types<\/a> instead of fully specifying), you get <strong>very<\/strong><strong> useful<\/strong> feedback as you code<\/li>\n<\/ul>\n<\/li>\n<li><a class=\"external-link\" href=\"https:\/\/github.com\/facebook\/flow\/blob\/master\/Changelog.md\" rel=\"nofollow\">Flow updates regularly<\/a> with improvements<\/li>\n<li>Flow is a Facebook thing, so the integration with React is great, <a class=\"external-link\" href=\"https:\/\/medium.com\/flow-type\/even-better-support-for-react-in-flow-25b0a3485627\" rel=\"nofollow\">even if it changes drastically<\/a>. This happened to me and tool they distributed to upgrade syntax worked great<\/li>\n<li>You support one evil mega corporation over another evil mega corporation<\/li>\n<li>You can use Flow with no transpilation<\/li>\n<\/ul>\n<h2 id=\"FlowType-Criticisms\"><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Criticisms<\/span><\/h2>\n<ul>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">For &#8220;gradual&#8221; typing, Flow type is heavy handed (but getting better).<\/span>\n<ol>\n<li><a class=\"external-link\" href=\"https:\/\/github.com\/facebook\/flow\/issues\/3316\" rel=\"nofollow\">&#8220;weak&#8221; mode might be deprecated<\/a>. &#8220;It makes incremental adoption of flow much easier for those of us who are attempting to add it to a codebase that was largely written without the guard rails that typing provides.&#8221; UPDATE: weak mode isn&#8217;t going away anytime soon<\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">It&#8217;s supposed to infer type, but it feels not that great. It&#8217;s not as good as humans. Flow gets especially annoying with object destructuring.<br \/>\n<\/span><\/li>\n<\/ol>\n<\/li>\n<li>\n<p class=\"auto-cursor-target\"><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Objects have to be fully spec&#8217;ed out or it&#8217;s an error, for example, you can&#8217;t add arbitrary properties to an Object. UPDATE: the <a class=\"external-link\" href=\"https:\/\/flow.org\/en\/docs\/types\/objects\/#toc-optional-object-type-properties\" rel=\"nofollow\">documentation about optional properties<\/a> is much better UPDATE2 They call these sealed vs unsealed UPDATE3 They&#8217;re going to transition to &#8220;<a href=\"https:\/\/medium.com\/flow-type\/on-the-roadmap-exact-objects-by-default-16b72933c5cf\">exact objects by default<\/a>&#8220;.<br \/>\n<\/span><\/p>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\" data-macro-id=\"558b76e0-7fd6-49bb-bfd7-4461ab4fca42\">\n<div class=\"codeContent panelContent pdl\">\n<div>\n<div id=\"highlighter_236851\" class=\"syntaxhighlighter sh-default nogutter jscript\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"jscript plain\">const a = {<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">foo: <\/code><code class=\"jscript string\">'hi'<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"jscript plain\">};<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"jscript comments\">\/\/ property `bar` Property not found in object literal<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"jscript plain\">a.bar = <\/code><code class=\"jscript string\">'uh oh'<\/code><code class=\"jscript plain\">;<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"jscript comments\">\/\/ you're supposed to do this instead<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"jscript plain\">const b: {foo: string, bar?: string} = {<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">foo: 'hi<\/code><code class=\"jscript string\">'<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"jscript string\">};<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"jscript string\">b.bar = '<\/code><code class=\"jscript plain\">well ok';<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Flow has no mechanism for turning off or ignoring some kinds of errors besides the\u00c2\u00a0<code>$FlowFixMe<\/code> suppression comment, and Flow can&#8217;t infer everything so your&#8217;e gonna either add a lot of <code>$FlowFixMe<\/code>s or defensive statements.<br \/>\n<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\"><code>.flowconfig<\/code> is not well documented<br \/>\n<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">The Flow binary is extremely finicky. I&#8217;ve caught it stealing all my CPU. It&#8217;s slow. In the Atom integration, you have to run code through twice to before you see an error. Which means if you fix something, you won&#8217;t get feedback until your seconds save. UPDATE: This gets better with every release, but it&#8217;s still really fragile. The first <code>flow<\/code> check can take 30 seconds to run while it warms up, even longer with monorepos.<br \/>\n<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">The syntax consumes a lot of lines, and results in very long lines because you have to describe large objects on one line. Especially since I only use comment syntax.<br \/>\n<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\"><a class=\"external-link\" href=\"https:\/\/flowtype.org\/blog\/2015\/02\/20\/Flow-Comments.html\" rel=\"nofollow\">Flow comment syntax<\/a> is poorly documented. All the literature assumes you&#8217;re using the syntax that requires a build step to remove Flow annotation.<br \/>\n<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">If you&#8217;re not using Flow comment syntax, all your annotations are being stripped in the artifact. Meaning consumers of your package won&#8217;t see annotations.<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">If you&#8217;re defining your own types in a <code>myLibDef.js<\/code>, Eslint will go nuts. You have to install the <a class=\"external-link\" href=\"https:\/\/github.com\/gajus\/eslint-plugin-flowtype\" rel=\"nofollow\">flowtype plugin<\/a> (see addendum).<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\"><a class=\"external-link\" href=\"https:\/\/github.com\/facebook\/flow\/blob\/master\/Changelog.md\" rel=\"nofollow\">Flow changes quickly<\/a> and is pre 1.0, so there are frequent, breaking syntax changes<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">For example, in Flow 0.55, libraries that used Bluebird <a class=\"external-link\" href=\"https:\/\/github.com\/flowtype\/flow-typed\/issues\/1272\" rel=\"nofollow\">started erroring<\/a>, and this has happened before<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Flow will often throw stupid errors, requiring <code>$FlowFixMe<\/code> comments often<\/span>\n<ul>\n<li><a class=\"external-link\" href=\"https:\/\/github.com\/facebook\/flow\/issues\/2826\" rel=\"nofollow\">Flow considers all getters\/setters unsafe<\/a>, even if they don&#8217;t have side effects<\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Flow doesn&#8217;t realize that HTMLAnchorElement is a subclass of HTMLElement<\/span><\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">Flow has trouble with DOM APIs<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">The <a class=\"external-link\" href=\"https:\/\/github.com\/flowtype\/flow-typed\/\" rel=\"nofollow\">https:\/\/github.com\/flowtype\/flow-typed\/<\/a> ecosystem for third party type definitions is a trainwreck<\/span><\/li>\n<\/ul>\n<h2 id=\"FlowType-TypeScript\"><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">TypeScript<\/span><\/h2>\n<p><span class=\"inline-comment-marker\" data-ref=\"68653ce3-0cea-4414-918b-053b081b1a7f\">I initially chose Flow because TypeScript required a transpilation step. Since then, TypeScript has come out with a comment syntax based on JSDoc, but it seems to be <em>extremely<\/em> limited. <a class=\"external-link\" href=\"https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/JSDoc-support-in-JavaScript\" rel=\"nofollow\">https:\/\/github.com\/Microsoft\/TypeScript\/wiki\/JSDoc-support-in-JavaScript<\/a>. I read a lot of TypeScript but don&#8217;t write it, and it still feels ham-fisted compared to Flow. I especially don&#8217;t like how browsing TypeScript in GitHub, it&#8217;s hard read business logic when over half the lines are type definitions.<br \/>\n<\/span><\/p>\n<h2>Best practices with Flow<\/h2>\n<ol>\n<li>Use comment syntax<\/li>\n<li>Start very general, then gradually refine your types to be more specific<\/li>\n<\/ol>\n<h2 id=\"FlowType-Addendum\">Addendum<\/h2>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\" data-macro-id=\"95a90186-a1c7-4be2-8cb7-e90937738880\">\n<div class=\"codeHeader panelHeader pdl\"><b>eslintrc.js<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<div>\n<div id=\"highlighter_830272\" class=\"syntaxhighlighter sh-default nogutter jscript\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"jscript plain\">{<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript comments\">\/\/ Allow underlines and Flow comment syntax<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript string\">'spaced-comment'<\/code><code class=\"jscript plain\">: [<\/code><code class=\"jscript string\">'error'<\/code><code class=\"jscript plain\">, <\/code><code class=\"jscript string\">'always'<\/code><code class=\"jscript plain\">, {exceptions: [<\/code><code class=\"jscript string\">'\/'<\/code><code class=\"jscript plain\">], markers: [<\/code><code class=\"jscript string\">':'<\/code><code class=\"jscript plain\">, <\/code><code class=\"jscript string\">'::'<\/code><code class=\"jscript plain\">]}],<\/code><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">plugins: [<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">...,<\/code><\/div>\n<div class=\"line number6 index5 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript string\">'flowtype'<\/code><\/div>\n<div class=\"line number7 index6 alt2\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">],<\/code><\/div>\n<div class=\"line number8 index7 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">rules: {<\/code><\/div>\n<div class=\"line number9 index8 alt2\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript string\">'flowtype\/define-flow-type'<\/code><code class=\"jscript plain\">: 1,<\/code><\/div>\n<div class=\"line number10 index9 alt1\"><code class=\"jscript spaces\">\u00c2\u00a0\u00c2\u00a0<\/code><code class=\"jscript plain\">}<\/code><\/div>\n<div class=\"line number11 index10 alt2\"><code class=\"jscript plain\">}<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"code panel pdl conf-macro output-block\" data-hasbody=\"true\" data-macro-name=\"code\" data-macro-id=\"8a166e58-b3e8-4640-b7d5-14e08fba3139\">\n<div class=\"codeHeader panelHeader pdl\"><b>.flowconfig<\/b><\/div>\n<div class=\"codeContent panelContent pdl\">\n<div>\n<div id=\"highlighter_285025\" class=\"syntaxhighlighter sh-default nogutter text\">\n<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td class=\"code\">\n<div class=\"container\" title=\"Hint: double-click to select code\">\n<div class=\"line number1 index0 alt2\"><code class=\"text plain\">[include]<\/code><\/div>\n<div class=\"line number2 index1 alt1\"><code class=\"text plain\">src\/<\/code><\/div>\n<div class=\"line number3 index2 alt2\"><\/div>\n<div class=\"line number4 index3 alt1\"><code class=\"text plain\">[ignore]<\/code><\/div>\n<div class=\"line number5 index4 alt2\"><code class=\"text plain\">.*\/node_modules\/&lt;add an entry for every problematic package, don't ignore all node_modules&gt;<\/code><\/div>\n<\/div>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2 id=\"FlowType-Furtherreading\">Further reading<\/h2>\n<ul>\n<li><span class=\"js-issue-title\"><a class=\"external-link\" href=\"https:\/\/blog.acolyer.org\/2017\/09\/19\/to-type-or-not-to-type-quantifying-detectable-bugs-in-javascript\/\" rel=\"nofollow\">https:\/\/blog.acolyer.org\/2017\/09\/19\/to-type-or-not-to-type-quantifying-detectable-bugs-in-javascript\/<\/a><\/span><\/li>\n<\/ul>\n<p>Flow was version 0.86.0 as of writing<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Getting started Getting fast feedback in your IDE is vital to having a happy developer experience. Flow adds that value for me for JavaScript programming. Atom Install ide-flowtype. I just switched from the lighter-weight linter-flow and I&#8217;m liking it. The good parts You can use Flow with no transpilation You can use Flow with no&hellip;<\/p>\n <a href=\"https:\/\/www.crccheck.com\/blog\/flow-type-coding-in-javascript-with-guardrails\/\" title=\"Flow Type for coding in JavaScript with guardrails\" class=\"entry-more-link\"><span>Read More<\/span> <span class=\"screen-reader-text\">Flow Type for coding in JavaScript with guardrails<\/span><\/a>","protected":false},"author":2,"featured_media":826,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"Layout":"","footnotes":""},"categories":[50,4],"tags":[12],"class_list":["entry","author-showmewhatyougot","post-823","post","type-post","status-publish","format-standard","has-post-thumbnail","category-best-practices","category-technical","tag-js"],"_links":{"self":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/823","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/comments?post=823"}],"version-history":[{"count":2,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/823\/revisions"}],"predecessor-version":[{"id":825,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/posts\/823\/revisions\/825"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/media\/826"}],"wp:attachment":[{"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/media?parent=823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/categories?post=823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.crccheck.com\/blog\/wp-json\/wp\/v2\/tags?post=823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}