<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <id>https://flow.org/blog</id>
    <title>Flow Blog</title>
    <updated>2024-04-03T00:00:00.000Z</updated>
    <generator>https://github.com/jpmonette/feed</generator>
    <link rel="alternate" href="https://flow.org/blog"/>
    <subtitle>Flow Blog</subtitle>
    <icon>https://flow.org/img/favicon.png</icon>
    <entry>
        <title type="html"><![CDATA[New Flow Language Features for React]]></title>
        <id>https://flow.org/blog/2024/04/03/New-Flow-Language-Features-for-React</id>
        <link href="https://flow.org/blog/2024/04/03/New-Flow-Language-Features-for-React"/>
        <updated>2024-04-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow is excited to announce Component Syntax, adding first-class support for React primitives such as components and hooks to the Flow language. These features bring improved ergonomics, expressiveness, and static enforcement for many of the Rules of React.]]></summary>
        <content type="html"><![CDATA[<p>Flow is excited to announce Component Syntax, adding first-class support for React primitives such as components and hooks to the Flow language. These features bring improved ergonomics, expressiveness, and static enforcement for many of the Rules of React.</p>]]></content>
        <author>
            <name>Alex Taylor &amp; Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Conditional Types]]></title>
        <id>https://flow.org/blog/2024/03/05/Announcing-Conditional-Types</id>
        <link href="https://flow.org/blog/2024/03/05/Announcing-Conditional-Types"/>
        <updated>2024-03-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Conditional types allow you to choose between two different output types by inspecting an input type.]]></summary>
        <content type="html"><![CDATA[<p>Conditional types allow you to choose between two different output types by inspecting an input type.</p>]]></content>
        <author>
            <name>Sam Zhou</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing User Defined Type Guards in Flow]]></title>
        <id>https://flow.org/blog/2024/03/05/Announcing-User-Defined-Type-Guards-in-Flow</id>
        <link href="https://flow.org/blog/2024/03/05/Announcing-User-Defined-Type-Guards-in-Flow"/>
        <updated>2024-03-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow now lets you define a function that encodes a type predicate over its parameter.]]></summary>
        <content type="html"><![CDATA[<p>Flow now lets you define a function that encodes a type predicate over its parameter.</p>]]></content>
        <author>
            <name>Panagiotis Vekris</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New type casting syntax for Flow: 'as']]></title>
        <id>https://flow.org/blog/2024/02/06/New-type-casting-syntax-for-Flow-as</id>
        <link href="https://flow.org/blog/2024/02/06/New-type-casting-syntax-for-Flow-as"/>
        <updated>2024-02-06T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[To make it easier for new users to get started with Flow, we’re updating our type casting syntax to use 'as'.]]></summary>
        <content type="html"><![CDATA[<p>To make it easier for new users to get started with Flow, we’re updating our type casting syntax to use 'as'.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Improved Flow Docs and Try Flow]]></title>
        <id>https://flow.org/blog/2023/09/19/Improved-Flow-Docs-and-Try-Flow</id>
        <link href="https://flow.org/blog/2023/09/19/Improved-Flow-Docs-and-Try-Flow"/>
        <updated>2023-09-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We’ve refreshed our documentation, and added the ability to configure options and lints in Try Flow!]]></summary>
        <content type="html"><![CDATA[<p>We’ve refreshed our documentation, and added the ability to configure options and lints in Try Flow!</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing 5 new Flow tuple type features]]></title>
        <id>https://flow.org/blog/2023/08/17/Announcing-5-new-Flow-tuple-type-features</id>
        <link href="https://flow.org/blog/2023/08/17/Announcing-5-new-Flow-tuple-type-features"/>
        <updated>2023-08-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Labeled tuple elements, read-only tuples, optional tuple elements, tuple spread, and more.]]></summary>
        <content type="html"><![CDATA[<p>Labeled tuple elements, read-only tuples, optional tuple elements, tuple spread, and more.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flow can now detect unused Promises]]></title>
        <id>https://flow.org/blog/2023/04/10/Unused-Promise</id>
        <link href="https://flow.org/blog/2023/04/10/Unused-Promise"/>
        <updated>2023-04-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As of v0.201.0, Flow can now lint against unused/floating Promises. Unused promises can be dangerous,]]></summary>
        <content type="html"><![CDATA[<p>As of v0.201.0, Flow can now lint against unused/floating Promises. Unused promises can be dangerous,
because errors are potentially unhandled, and the code may not execute in the intended order. They are
usually mistakes that Flow is perfectly positioned to warn you about.</p>]]></content>
        <author>
            <name>David Richey</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Partial & Required Flow utility types + catch annotations]]></title>
        <id>https://flow.org/blog/2023/03/15/Announcing-Partial-and-Required-Flow-utility-types-and-catch-annotations</id>
        <link href="https://flow.org/blog/2023/03/15/Announcing-Partial-and-Required-Flow-utility-types-and-catch-annotations"/>
        <updated>2023-03-15T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Starting in Flow version 0.201, make an object type’s fields all optional using Partial (use instead of the unsafe $Shape),]]></summary>
        <content type="html"><![CDATA[<p>Starting in Flow version 0.201, make an object type’s fields all optional using <code>Partial&lt;ObjType&gt;</code> (use instead of the unsafe <code>$Shape</code>),
and make an object type’s optional fields required with <code>Required&lt;ObjType&gt;</code>.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Exact object types by default, by default]]></title>
        <id>https://flow.org/blog/2023/02/16/Exact-object-types-by-default-by-default</id>
        <link href="https://flow.org/blog/2023/02/16/Exact-object-types-by-default-by-default"/>
        <updated>2023-02-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We announced 5 years ago a plan to eventually make exact object types the default. We are now proceeding with this plan.]]></summary>
        <content type="html"><![CDATA[<p>We announced 5 years ago a plan to eventually make exact object types the default. We are now proceeding with this plan.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Local Type Inference for Flow]]></title>
        <id>https://flow.org/blog/2023/01/17/Local-Type-Inference</id>
        <link href="https://flow.org/blog/2023/01/17/Local-Type-Inference"/>
        <updated>2023-01-17T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Local Type Inference makes Flow’s inference behavior more reliable and predictable, by modestly increasing Flow’s annotation requirement, bringing it closer to industry standard and capitalizing on increasingly strongly and explicitly typed codebases.]]></summary>
        <content type="html"><![CDATA[<p>Local Type Inference makes Flow’s inference behavior more reliable and predictable, by modestly increasing Flow’s annotation requirement, bringing it closer to industry standard and capitalizing on increasingly strongly and explicitly typed codebases.</p>]]></content>
        <author>
            <name>Sam Zhou</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Improved handling of the empty object in Flow]]></title>
        <id>https://flow.org/blog/2022/10/20/Improved-handling-of-the-empty-object-in-Flow</id>
        <link href="https://flow.org/blog/2022/10/20/Improved-handling-of-the-empty-object-in-Flow"/>
        <updated>2022-10-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow handled the empty object literal {} in a permissive but unsafe way. The fix described in this post increases safety and predictability, but requires using different patterns and behavior.]]></summary>
        <content type="html"><![CDATA[<p>Flow handled the empty object literal {} in a permissive but unsafe way. The fix described in this post increases safety and predictability, but requires using different patterns and behavior.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Requiring More Annotations to Functions and Classes in Flow]]></title>
        <id>https://flow.org/blog/2022/09/30/Requiring-More-Annotations-on-Functions-and-Classes</id>
        <link href="https://flow.org/blog/2022/09/30/Requiring-More-Annotations-on-Functions-and-Classes"/>
        <updated>2022-09-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow will now require more annotations to functions and classes.]]></summary>
        <content type="html"><![CDATA[<p>Flow will now require more annotations to functions and classes.</p>]]></content>
        <author>
            <name>Sam Zhou</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New Flow Language Rule: Constrained Writes]]></title>
        <id>https://flow.org/blog/2022/08/05/New-Flow-Language-Rule-Constrained-Writes</id>
        <link href="https://flow.org/blog/2022/08/05/New-Flow-Language-Rule-Constrained-Writes"/>
        <updated>2022-08-05T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow is releasing a new language rule that determines the type of an unannotated variable at its initialization. Along with these new rules come several fixes to soundness bugs that were causing refinements to not be invalidated.]]></summary>
        <content type="html"><![CDATA[<p>Flow is releasing a new language rule that determines the type of an unannotated variable at its initialization. Along with these new rules come several fixes to soundness bugs that were causing refinements to not be invalidated.</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing: Local Type Inference for Flow]]></title>
        <id>https://flow.org/blog/2021/09/27/Introducing-Local-Type-Inference-for-Flow</id>
        <link href="https://flow.org/blog/2021/09/27/Introducing-Local-Type-Inference-for-Flow"/>
        <updated>2021-09-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We're replacing Flow’s current inference engine with a system that behaves more predictably and can be reasoned about more locally.]]></summary>
        <content type="html"><![CDATA[<p>We're replacing Flow’s current inference engine with a system that behaves more predictably and can be reasoned about more locally.</p>]]></content>
        <author>
            <name>Michael Vitousek</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Flow Enums]]></title>
        <id>https://flow.org/blog/2021/09/13/Introducing-Flow-Enums</id>
        <link href="https://flow.org/blog/2021/09/13/Introducing-Flow-Enums"/>
        <updated>2021-09-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow Enums are an opt-in feature which allow you to define a fixed set of constants which create their own type.]]></summary>
        <content type="html"><![CDATA[<p>Flow Enums are an opt-in feature which allow you to define a fixed set of constants which create their own type.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[TypeScript Enums vs. Flow Enums]]></title>
        <id>https://flow.org/blog/2021/09/13/TypeScript-Enums-vs-Flow-Enums</id>
        <link href="https://flow.org/blog/2021/09/13/TypeScript-Enums-vs-Flow-Enums"/>
        <updated>2021-09-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[A comparison of the enums features of TypeScript and Flow.]]></summary>
        <content type="html"><![CDATA[<p>A comparison of the enums features of TypeScript and Flow.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Flow Indexed Access Types]]></title>
        <id>https://flow.org/blog/2021/07/21/Introducing-Flow-Indexed-Access-Types</id>
        <link href="https://flow.org/blog/2021/07/21/Introducing-Flow-Indexed-Access-Types"/>
        <updated>2021-07-21T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow’s Indexed Access Types are a new type annotation syntax that allows you to get the type of a property from an object, array, or tuple type.]]></summary>
        <content type="html"><![CDATA[<p>Flow’s Indexed Access Types are a new type annotation syntax that allows you to get the type of a property from an object, array, or tuple type.</p>]]></content>
        <author>
            <name>George Zahariev</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Sound Typing for 'this' in Flow]]></title>
        <id>https://flow.org/blog/2021/06/02/Sound-Typing-for-this-in-Flow</id>
        <link href="https://flow.org/blog/2021/06/02/Sound-Typing-for-this-in-Flow"/>
        <updated>2021-06-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Improvements in soundness for this-typing in Flow, including the ability to annotate this on functions and methods.]]></summary>
        <content type="html"><![CDATA[<p>Improvements in soundness for <code>this</code>-typing in Flow, including the ability to annotate <code>this</code> on functions and methods.</p>]]></content>
        <author>
            <name>Daniel Sainati</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Clarity on Flow's Direction and Open Source Engagement]]></title>
        <id>https://flow.org/blog/2021/05/25/Clarity-on-Flows-Direction-and-Open-Source-Engagement</id>
        <link href="https://flow.org/blog/2021/05/25/Clarity-on-Flows-Direction-and-Open-Source-Engagement"/>
        <updated>2021-05-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[An update on Flow's direction and open source engagement.]]></summary>
        <content type="html"><![CDATA[<p>An update on Flow's direction and open source engagement.</p>]]></content>
        <author>
            <name>Vladan Djeric</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Types-First the only supported mode in Flow (Jan 2021)]]></title>
        <id>https://flow.org/blog/2020/12/01/Types-first-the-only-supported-mode-in-flow</id>
        <link href="https://flow.org/blog/2020/12/01/Types-first-the-only-supported-mode-in-flow"/>
        <updated>2020-12-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Types-First will become the only mode in Flow in v0.143 (mid Jan 2021).]]></summary>
        <content type="html"><![CDATA[<p>Types-First will become the only mode in Flow in v0.143 (mid Jan 2021).</p>]]></content>
        <author>
            <name>Panagiotis Vekris</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Flow's Improved Handling of Generic Types]]></title>
        <id>https://flow.org/blog/2020/11/16/Flows-Improved-Handling-of-Generic-Types</id>
        <link href="https://flow.org/blog/2020/11/16/Flows-Improved-Handling-of-Generic-Types"/>
        <updated>2020-11-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow has improved its handling of generic types by banning unsafe behaviors previously allowed and clarifying error messages.]]></summary>
        <content type="html"><![CDATA[<p>Flow has improved its handling of generic types by banning unsafe behaviors previously allowed and clarifying error messages.</p>]]></content>
        <author>
            <name>Michael Vitousek</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Types-First: A Scalable New Architecture for Flow]]></title>
        <id>https://flow.org/blog/2020/05/18/Types-First-A-Scalable-New-Architecture-for-Flow</id>
        <link href="https://flow.org/blog/2020/05/18/Types-First-A-Scalable-New-Architecture-for-Flow"/>
        <updated>2020-05-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow Types-First mode is out! It unlocks Flow’s potential at scale by leveraging fully typed module boundaries. Read more in our latest blog post.]]></summary>
        <content type="html"><![CDATA[<p>Flow Types-First mode is out! It unlocks Flow’s potential at scale by leveraging fully typed module boundaries. Read more in our latest blog post.</p>]]></content>
        <author>
            <name>Panagiotis Vekris</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Making Flow error suppressions more specific]]></title>
        <id>https://flow.org/blog/2020/03/16/Making-Flow-error-suppressions-more-specific</id>
        <link href="https://flow.org/blog/2020/03/16/Making-Flow-error-suppressions-more-specific"/>
        <updated>2020-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We’re improving Flow error suppressions so that they don’t accidentally hide errors.]]></summary>
        <content type="html"><![CDATA[<p>We’re improving Flow error suppressions so that they don’t accidentally hide errors.</p>]]></content>
        <author>
            <name>Daniel Sainati</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What we’re building in 2020]]></title>
        <id>https://flow.org/blog/2020/03/09/What-were-building-in-2020</id>
        <link href="https://flow.org/blog/2020/03/09/What-were-building-in-2020"/>
        <updated>2020-03-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Learn about how Flow will improve in 2020.]]></summary>
        <content type="html"><![CDATA[<p>Learn about how Flow will improve in 2020.</p>]]></content>
        <author>
            <name>Andrew Pardoe</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Improvements to Flow in 2019]]></title>
        <id>https://flow.org/blog/2020/02/19/Improvements-to-Flow-in-2019</id>
        <link href="https://flow.org/blog/2020/02/19/Improvements-to-Flow-in-2019"/>
        <updated>2020-02-19T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Take a look back at improvements we made to Flow in 2019.]]></summary>
        <content type="html"><![CDATA[<p>Take a look back at improvements we made to Flow in 2019.</p>]]></content>
        <author>
            <name>Andrew Pardoe</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[How to upgrade to exact-by-default object type syntax]]></title>
        <id>https://flow.org/blog/2020/01/29/How-to-Upgrade-to-exact-by-default-object-type-syntax</id>
        <link href="https://flow.org/blog/2020/01/29/How-to-Upgrade-to-exact-by-default-object-type-syntax"/>
        <updated>2020-01-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Object types will become exact-by-default. Read this post to learn how to get your code ready!]]></summary>
        <content type="html"><![CDATA[<p>Object types will become exact-by-default. Read this post to learn how to get your code ready!</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Spreads: Common Errors & Fixes]]></title>
        <id>https://flow.org/blog/2019/10/30/Spreads-Common-Errors-and-Fixes</id>
        <link href="https://flow.org/blog/2019/10/30/Spreads-Common-Errors-and-Fixes"/>
        <updated>2019-10-30T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Fixes to object spreads will expose errors in your codebase. Read more about common errors and how to fix them.]]></summary>
        <content type="html"><![CDATA[<p>Fixes to object spreads will expose errors in your codebase. Read more about common errors and how to fix them.</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Live Flow errors in your IDE]]></title>
        <id>https://flow.org/blog/2019/10/25/Live-Flow-Errors-in-your-IDE</id>
        <link href="https://flow.org/blog/2019/10/25/Live-Flow-Errors-in-your-IDE"/>
        <updated>2019-10-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Live errors while you type makes Flow feel faster in your IDE!]]></summary>
        <content type="html"><![CDATA[<p>Live errors while you type makes Flow feel faster in your IDE!</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Coming Soon: Changes to Object Spreads]]></title>
        <id>https://flow.org/blog/2019/08/20/Changes-to-Object-Spreads</id>
        <link href="https://flow.org/blog/2019/08/20/Changes-to-Object-Spreads"/>
        <updated>2019-08-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Changes are coming to how Flow models object spreads! Learn more in this post.]]></summary>
        <content type="html"><![CDATA[<p>Changes are coming to how Flow models object spreads! Learn more in this post.</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Upgrading Flow Codebases]]></title>
        <id>https://flow.org/blog/2019/4/9/Upgrading-Flow-Codebases</id>
        <link href="https://flow.org/blog/2019/4/9/Upgrading-Flow-Codebases"/>
        <updated>2019-04-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Having trouble upgrading from 0.84.0? Read about how the Flow team upgrades Flow at Facebook!]]></summary>
        <content type="html"><![CDATA[<p>Having trouble upgrading from 0.84.0? Read about how the Flow team upgrades Flow at Facebook!</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[A More Responsive Flow]]></title>
        <id>https://flow.org/blog/2019/2/8/A-More-Responsive-Flow</id>
        <link href="https://flow.org/blog/2019/2/8/A-More-Responsive-Flow"/>
        <updated>2019-02-08T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow 0.92 improves on the Flow developer experience.]]></summary>
        <content type="html"><![CDATA[<p>Flow 0.92 improves on the Flow developer experience.</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[What the Flow Team Has Been Up To]]></title>
        <id>https://flow.org/blog/2019/1/28/What-the-flow-team-has-been-up-to</id>
        <link href="https://flow.org/blog/2019/1/28/What-the-flow-team-has-been-up-to"/>
        <updated>2019-01-28T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Take a look at what the Flow was up to in 2018.]]></summary>
        <content type="html"><![CDATA[<p>Take a look at what the Flow was up to in 2018.</p>]]></content>
        <author>
            <name>Avik Chaudhuri</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Supporting React.forwardRef and Beyond]]></title>
        <id>https://flow.org/blog/2018/12/13/React-Abstract-Component</id>
        <link href="https://flow.org/blog/2018/12/13/React-Abstract-Component"/>
        <updated>2018-12-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We made some major changes to our React model to better model new React components. Let's]]></summary>
        <content type="html"><![CDATA[<p>We made some major changes to our React model to better model new React components. Let's
talk about React.AbstractComponent!</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Asking for Required Annotations]]></title>
        <id>https://flow.org/blog/2018/10/29/Asking-for-Required-Annotations</id>
        <link href="https://flow.org/blog/2018/10/29/Asking-for-Required-Annotations"/>
        <updated>2018-10-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow will be asking for more annotations starting in 0.85.0. Learn how]]></summary>
        <content type="html"><![CDATA[<p>Flow will be asking for more annotations starting in 0.85.0. Learn how
to deal with these errors in our latest blog post.</p>]]></content>
        <author>
            <name>Sam Goldman</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[On the Roadmap: Exact Objects by Default]]></title>
        <id>https://flow.org/blog/2018/10/18/Exact-Objects-By-Default</id>
        <link href="https://flow.org/blog/2018/10/18/Exact-Objects-By-Default"/>
        <updated>2018-10-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are changing object types to be exact by default. We'll be releasing codemods to help you upgrade.]]></summary>
        <content type="html"><![CDATA[<p>We are changing object types to be exact by default. We'll be releasing codemods to help you upgrade.</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New Flow Errors on Unknown Property Access in Conditionals]]></title>
        <id>https://flow.org/blog/2018/03/16/New-Flow-Errors-on-Unknown-Property-Access-in-Conditionals</id>
        <link href="https://flow.org/blog/2018/03/16/New-Flow-Errors-on-Unknown-Property-Access-in-Conditionals"/>
        <updated>2018-03-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[TL;DR: Starting in 0.68.0, Flow will now error when you access unknown]]></summary>
        <content type="html"><![CDATA[<p>TL;DR: Starting in 0.68.0, Flow will now error when you access unknown
properties in conditionals.</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Better Flow Error Messages for the JavaScript Ecosystem]]></title>
        <id>https://flow.org/blog/2018/02/20/Better-Flow-Error-Messages-for-the-Javascript-Ecosystem</id>
        <link href="https://flow.org/blog/2018/02/20/Better-Flow-Error-Messages-for-the-Javascript-Ecosystem"/>
        <updated>2018-02-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Over the last year, the Flow team has been slowly auditing and improving all the]]></summary>
        <content type="html"><![CDATA[<p>Over the last year, the Flow team has been slowly auditing and improving all the
possible error messages generated by the type checker. In Flow 0.66 we’re
excited to announce a new error message format designed to decrease the time it
takes you to read and fix each bug Flow finds.</p>]]></content>
        <author>
            <name>Caleb Meredith</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Typing Higher-Order Components in Recompose With Flow]]></title>
        <id>https://flow.org/blog/2017/09/03/Flow-Support-in-Recompose</id>
        <link href="https://flow.org/blog/2017/09/03/Flow-Support-in-Recompose"/>
        <updated>2017-09-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[One month ago Recompose landed an]]></summary>
        <content type="html"><![CDATA[<p>One month ago <a href="https://github.com/acdlite/recompose" target="_blank" rel="noopener noreferrer">Recompose</a> landed an
official Flow library definition. The definitions were a long time coming,
considering the original PR was created by
<a href="https://twitter.com/GiulioCanti" target="_blank" rel="noopener noreferrer">@GiulioCanti</a> a year ago.</p>]]></content>
        <author>
            <name>Ivan Starkov</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Private Object Properties Using Flow’s Opaque Type Aliases]]></title>
        <id>https://flow.org/blog/2017/08/25/Private-Object-Properties-Using-Flows-Opaque-Type-Aliases</id>
        <link href="https://flow.org/blog/2017/08/25/Private-Object-Properties-Using-Flows-Opaque-Type-Aliases"/>
        <updated>2017-08-25T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[In the last few weeks, a proposal for private class fields in Javascript reached]]></summary>
        <content type="html"><![CDATA[<p>In the last few weeks, a proposal for <a href="https://github.com/tc39/proposal-class-fields" target="_blank" rel="noopener noreferrer">private class fields in Javascript</a> reached
stage 3. This is going to be a great way to hide implementation details away
from users of your classes. However, locking yourself in to an OOP style of
programming is not always ideal if you prefer a more functional style. Let’s
talk about how you can use Flow’s <a href="https://flow.org/en/docs/types/opaque-types/" target="_blank" rel="noopener noreferrer">opaque type aliases</a> to get private properties
on any object type.</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Even Better Support for React in Flow]]></title>
        <id>https://flow.org/blog/2017/08/16/Even-Better-Support-for-React-in-Flow</id>
        <link href="https://flow.org/blog/2017/08/16/Even-Better-Support-for-React-in-Flow"/>
        <updated>2017-08-16T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The first version of Flow support for React was a magical implementation of]]></summary>
        <content type="html"><![CDATA[<p>The first version of Flow support for React was a magical implementation of
<code>React.createClass()</code>. Since then, React has evolved significantly. It is time
to rethink how Flow models React.</p>]]></content>
        <author>
            <name>Caleb Meredith</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Linting in Flow]]></title>
        <id>https://flow.org/blog/2017/08/04/Linting-in-Flow</id>
        <link href="https://flow.org/blog/2017/08/04/Linting-in-Flow"/>
        <updated>2017-08-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow’s type information is useful for so much more than just proving your programs are correct. Introducing Flow linter.]]></summary>
        <content type="html"><![CDATA[<p>Flow’s type information is useful for so much more than just proving your programs are correct. Introducing Flow linter.</p>]]></content>
        <author>
            <name>Roger Ballard</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Opaque Type Aliases]]></title>
        <id>https://flow.org/blog/2017/07/27/Opaque-Types</id>
        <link href="https://flow.org/blog/2017/07/27/Opaque-Types"/>
        <updated>2017-07-27T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Do you ever wish that you could hide your implementation details away]]></summary>
        <content type="html"><![CDATA[<p>Do you ever wish that you could hide your implementation details away
from your users? Find out how opaque type aliases can get the job done!</p>]]></content>
        <author>
            <name>Jordan Brown</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Strict Checking of Function Call Arity]]></title>
        <id>https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity</id>
        <link href="https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity"/>
        <updated>2017-05-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[One of Flow's original goals was to be able to understand idiomatic JavaScript.]]></summary>
        <content type="html"><![CDATA[<p>One of Flow's original goals was to be able to understand idiomatic JavaScript.
In JavaScript, you can call a function with more arguments than the function
expects. Therefore, Flow never complained about calling a function with
extraneous arguments.</p><p>We are changing this behavior.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-arity">What is arity?<a href="#what-is-arity" class="hash-link" aria-label="Direct link to What is arity?" title="Direct link to What is arity?">​</a></h3><p>A function's <em>arity</em> is the number of arguments it expects. Since some functions
have optional parameters and some use rest parameters, we can define the
<em>minimum arity</em> as the smallest number of arguments it expects and the <em>maximum
arity</em> as the largest number of arguments it expects.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">no_args</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// arity of 0</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">two_args</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// arity of 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">optional_args</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> b</span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// min arity of 1, max arity of 2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">many_args</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain">rest</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// min arity of 1, no max arity</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="motivation">Motivation<a href="#motivation" class="hash-link" aria-label="Direct link to Motivation" title="Direct link to Motivation">​</a></h3><p>Consider the following code:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">add</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The author apparently thought the <code>add()</code> function adds up all its
arguments, and that <code>sum</code> will have the value <code>4</code>. However, only the first two
arguments are summed, and <code>sum</code> actually will have the value <code>2</code>. This is
obviously a bug, so why doesn't JavaScript or Flow complain?</p><p>And while the error in the above example is easy to see, in real code it's often
a lot harder to notice. For example, what is the value of <code>total</code> here:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> total </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">parseInt</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"10"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">parseFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"10.1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><code>"10"</code> in base 2 is <code>2</code> in decimal and <code>"10.1"</code> in base 2 is <code>2.5</code> in decimal.
So the author probably thought that <code>total</code> would be <code>4.5</code>. However, the correct
answer is <code>12.1</code>. <code>parseInt("10", 2)</code> does evaluates to <code>2</code>, as expected.
However, <code>parseFloat("10.1", 2)</code> evaluates to <code>10.1</code>. <code>parseFloat()</code> only takes
a single argument. The second argument is ignored!</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-javascript-allows-extraneous-arguments">Why JavaScript allows extraneous arguments<a href="#why-javascript-allows-extraneous-arguments" class="hash-link" aria-label="Direct link to Why JavaScript allows extraneous arguments" title="Direct link to Why JavaScript allows extraneous arguments">​</a></h3><p>At this point, you might feel like this is just an example of JavaScript making
terrible life decisions. However, this behavior is very convenient in a bunch of
situations!</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="callbacks">Callbacks<a href="#callbacks" class="hash-link" aria-label="Direct link to Callbacks" title="Direct link to Callbacks">​</a></h4><p>If you couldn't call a function with more arguments than it handles, then
mapping over an array would look like</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> doubled_arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">element</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> index</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> arr</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> element </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When you call <code>Array.prototype.map</code>, you pass in a callback. For each element in
the array, that callback is invoked and passed 3 arguments:</p><ol><li>The element</li><li>The index of the element</li><li>The array over which you're mapping</li></ol><p>However, your callback often only needs to reference the first argument: the
element. It's really nice that you can write</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> doubled_arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">element </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> element </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="stubbing">Stubbing<a href="#stubbing" class="hash-link" aria-label="Direct link to Stubbing" title="Direct link to Stubbing">​</a></h4><p>Sometimes I come across code like this</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">log</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token constant" style="color:#36acaa">DEBUG</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function-variable function" style="color:#d73a49">log</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">message</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">message</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Hello world"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The idea is that in a development environment, calling <code>log()</code> will output a
message, but in production it does nothing. Since you can call a
function with more arguments than it expects, it is easy to stub out <code>log()</code> in
production.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="variadic-functions-using-arguments">Variadic functions using <code>arguments</code><a href="#variadic-functions-using-arguments" class="hash-link" aria-label="Direct link to variadic-functions-using-arguments" title="Direct link to variadic-functions-using-arguments">​</a></h4><p>A variadic function is a function that can take an indefinite number of
arguments. The old-school way to write variadic functions in JavaScript is by
using <code>arguments</code>. For example</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sum_all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> arguments</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> ret </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> arguments</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ret</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> total </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sum_all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// returns 6</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>For all intents and purposes, <code>sum_all</code> appears like it takes no arguments. So
even though it appears to have an arity of 0, it is convenient that we can call
it with more arguments.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="changes-to-flow">Changes to Flow<a href="#changes-to-flow" class="hash-link" aria-label="Direct link to Changes to Flow" title="Direct link to Changes to Flow">​</a></h3><p>We think we have found a compromise which catches the motivating bugs without
breaking the convenience of JavaScript.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="calling-a-function">Calling a function<a href="#calling-a-function" class="hash-link" aria-label="Direct link to Calling a function" title="Direct link to Calling a function">​</a></h4><p>If a function has a maximum arity of N, then Flow will start complaining if you
call it with more than N arguments.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">test</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token number" style="color:#36acaa">1</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> num </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">parseFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"10.5"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                                    </span><span class="token operator" style="color:#393A34">^</span><span class="token plain"> unused </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> argument</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">   </span><span class="token number" style="color:#36acaa">19</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">parseFloat</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> mixed</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                                  </span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token operator" style="color:#393A34">^</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">expects</span><span class="token plain"> no more than </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> argument</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain"> </span><span class="token property-access maybe-class-name">See</span><span class="token plain"> lib</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">BUILTINS</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">/core.js:19</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="function-subtyping">Function subtyping<a href="#function-subtyping" class="hash-link" aria-label="Direct link to Function subtyping" title="Direct link to Function subtyping">​</a></h4><p>Flow will not change its function subtyping behavior. A function
with a smaller maximum arity is still a subtype of a function with a larger
maximum arity. This allows callbacks to still work as before.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name builtin">Array</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name constant" style="color:#36acaa">T</span><span class="token class-name operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token generic-function function" style="color:#d73a49">map</span><span class="token generic-function generic class-name operator" style="color:#393A34">&lt;</span><span class="token generic-function generic class-name constant" style="color:#36acaa">U</span><span class="token generic-function generic class-name operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function-variable function" style="color:#d73a49">callbackfn</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> index</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> array</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Array</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> thisArg</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">any</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token known-class-name class-name">Array</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">U</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> arr </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">,</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">4</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// No error, evaluates to [4,4,4]</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In this example, <code>() =&gt; number</code> is a subtype of <code>(number, number, Array&lt;number&gt;) =&gt; number</code>.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="stubbing-and-variadic-functions">Stubbing and variadic functions<a href="#stubbing-and-variadic-functions" class="hash-link" aria-label="Direct link to Stubbing and variadic functions" title="Direct link to Stubbing and variadic functions">​</a></h4><p>This will, unfortunately, cause Flow to complain about stubs and variadic
functions which are written using <code>arguments</code>. However, you can fix these by
using rest parameters</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">log</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain">rest</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sum_all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain">rest</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> ret </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> rest</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> ret </span><span class="token operator" style="color:#393A34">+=</span><span class="token plain"> rest</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">i</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> ret</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="rollout-plan">Rollout plan<a href="#rollout-plan" class="hash-link" aria-label="Direct link to Rollout plan" title="Direct link to Rollout plan">​</a></h3><p>Flow v0.46.0 will ship with strict function call arity turned off by default. It
can be enabled via your <code>.flowconfig</code> with the flag</p><div class="language-ini codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-ini codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">experimental.strict_call_arity=true</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flow v0.47.0 will ship with strict function call arity turned on and the
<code>experimental.strict_call_arity</code> flag will be removed.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="why-turn-this-on-over-two-releases">Why turn this on over two releases?<a href="#why-turn-this-on-over-two-releases" class="hash-link" aria-label="Direct link to Why turn this on over two releases?" title="Direct link to Why turn this on over two releases?">​</a></h4><p>This decouples the switch to strict checking of function call arity from the
release.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="why-not-keep-the-experimentalstrict_call_arity-flag">Why not keep the <code>experimental.strict_call_arity</code> flag?<a href="#why-not-keep-the-experimentalstrict_call_arity-flag" class="hash-link" aria-label="Direct link to why-not-keep-the-experimentalstrict_call_arity-flag" title="Direct link to why-not-keep-the-experimentalstrict_call_arity-flag">​</a></h4><p>This is a pretty core change. If we kept both behaviors, we'd have to test that
everything works with and without this change. As we add more flags, the number
of combinations grows exponentially, and Flow's behavior gets harder to reason
about. For this reason, we're choosing only one behavior: strict checking of
function call arity.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-do-you-think">What do you think?<a href="#what-do-you-think" class="hash-link" aria-label="Direct link to What do you think?" title="Direct link to What do you think?">​</a></h3><p>This change was motivated by feedback from Flow users. We really appreciate
all the members of our community who take the time to share their feedback with
us. This feedback is invaluable and helps us make Flow better, so please keep
it coming!</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Introducing Flow-Typed]]></title>
        <id>https://flow.org/blog/2016/10/13/Flow-Typed</id>
        <link href="https://flow.org/blog/2016/10/13/Flow-Typed"/>
        <updated>2016-10-13T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Having high-quality and community-driven library definitions (“libdefs”) are]]></summary>
        <content type="html"><![CDATA[<p>Having high-quality and community-driven library definitions (“libdefs”) are
important for having a great experience with Flow. Today, we are introducing
<strong>flow-typed</strong>: A <a href="https://github.com/flowtype/flow-typed/" target="_blank" rel="noopener noreferrer">repository</a> and
<a href="http://npmjs.org/packages/flow-typed" target="_blank" rel="noopener noreferrer">CLI tool</a> that represent the first parts
of a new workflow for building, sharing, and distributing Flow libdefs.</p><p>The goal of this project is to grow an ecosystem of libdefs that
<a href="https://medium.com/@thejameskyle/flow-mapping-an-object-373d64c44592" target="_blank" rel="noopener noreferrer">allows Flow's type inference to shine</a>
and that aligns with Flow's mission: To extract precise and <em>accurate</em> types
from real-world JavaScript. We've learned a lot from similar efforts like
DefinitelyTyped for TypeScript and we want to bring some of the lessons we've
learned to the Flow ecosystem.</p><p>Here are some of the objectives of this project:</p><ul><li>Libdefs should be <strong>versioned</strong> — both against the libraries they describe
<em>and</em> against the version(s) of Flow they are compatible with.</li><li>Libdefs should meet a <strong>high quality bar</strong>, including <strong>libdef tests</strong> to
ensure that their quality persists over time.</li><li>There must be a straightforward way to <strong>contribute libdef improvements over
time</strong> and for developers to <strong>benefit from those improvements</strong> over time.</li><li>The process of managing libdefs for a Flow project should be <strong>automated,
simple, and easy to get right</strong>.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="versioned--tested-libdefs">Versioned &amp; Tested Libdefs<a href="#versioned--tested-libdefs" class="hash-link" aria-label="Direct link to Versioned &amp; Tested Libdefs" title="Direct link to Versioned &amp; Tested Libdefs">​</a></h3><p>Anyone can contribute a libdef (or improve on an existing one), but when doing
so it's important that we maintain a high quality bar so that all developers
feel confident in the libdefs they are using. To address this, flow-typed
requires that all libdef contributions are explicitly versioned against both
the version of the library they are describing and the version(s) of Flow the
libdef is compatible with.</p><p>Additionally, all libdefs must be accompanied by tests that exercise the
important parts of the API and assert that they yield the correct types. By
including both version information and tests with each libdef, we can
automatically verify in Travis that the tests work as expected for all versions
of Flow a libdef is compatible with. Tests also help to ensure that future
changes to the libdef don't regress its features over time.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="automating-libdef-installation">Automating Libdef Installation<a href="#automating-libdef-installation" class="hash-link" aria-label="Direct link to Automating Libdef Installation" title="Direct link to Automating Libdef Installation">​</a></h3><p>We've built a simple CLI tool called <code>flow-typed</code> that helps to automate the
process of finding, installing, and upgrading libdefs in your Flow projects. It
uses the explicit version info associated with each libdef to find all
necessary libdefs based on your project's package.json dependencies. This
minimizes the work you need to do in order to pull in and update libdefs in
your projects.</p><p>You can get the flow-typed CLI using either yarn (<code>yarn global add flow-typed</code>)
or npm (<code>npm install -g flow-typed</code>).</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="installing-libdefs">Installing Libdefs<a href="#installing-libdefs" class="hash-link" aria-label="Direct link to Installing Libdefs" title="Direct link to Installing Libdefs">​</a></h3><p>Installing libdefs from the flow-typed repository is a matter of running a
single command on your project after installing your dependencies:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">&gt; yarn install # Or `npm install` if you're old-school :)</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">&gt; flow-typed install</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The <code>flow-typed install</code> command reads your project's package.json file,
queries the flow-typed repository for libdefs matching your dependencies, and
installs the correctly-versioned libdefs into the <code>flow-typed/</code> directory for
you. By default, Flow knows to look in the <code>flow-typed/</code> directory for libdefs
— so there is no additional configuration necessary.</p><p>Note that it's necessary to run this command <em>after</em> running <code>yarn</code> or
<code>npm install</code>. This is because this command will also generate stub libdefs for
you if one of your dependencies doesn't have types.</p><p>Once libdefs have been installed, <strong>we recommend that you check them in to your
project's repo</strong>. Libdefs in the flow-typed repository may be improved over
time (fixing a bug, more precise types, etc). If this happens for a libdef that
you depend on, you'll want to have control over when that update is applied to
your project. Periodically you can run <code>flow-typed update</code> to download any
libdef updates, verify that your project still typechecks, and the commit the
updates.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="why-not-just-use-npm-to-distribute-libdefs">Why Not Just Use Npm To Distribute Libdefs?<a href="#why-not-just-use-npm-to-distribute-libdefs" class="hash-link" aria-label="Direct link to Why Not Just Use Npm To Distribute Libdefs?" title="Direct link to Why Not Just Use Npm To Distribute Libdefs?">​</a></h3><p>Over time libdefs in the flow-typed repo may be updated to fix bugs, improve
accuracy, or make use of new Flow features that better describe the types of
the library. As a result, there are really 3 versions that apply to each
libdef: The version of the library being described, the current version of the
libdef in the flow-typed repo, and the version(s) of Flow the libdef is
compatible with.</p><p>If an update is made to some libdef that you use in your project after you've
already installed it, there's a good chance that update may find new type
errors in your project that were previously unknown. While it is certainly a
good thing to find errors that were previously missed, you'll want to have
control over when those changes get pulled in to your project.</p><p>This is the reason we advise that you commit your installed libdefs to version
control rather than rely on a system like npm+semver to download and install a
non-deterministic semver-ranged version from npm. Checking in your libdefs
ensures that all collaborators on your project have consistent output from Flow
at any given commit in version history.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="building-a-community">Building a Community<a href="#building-a-community" class="hash-link" aria-label="Direct link to Building a Community" title="Direct link to Building a Community">​</a></h3><p>This is first and foremost a community project. It was started by a community
member (hey <a href="https://github.com/splodingsocks" target="_blank" rel="noopener noreferrer">@splodingsocks</a>!) and has
already benefitted from hours of work by many others. Moreover, this will
continue to be a community effort: Anyone can create and/or help maintain a
libdef for any npm library. Authors may create libdefs for their packages when
publishing, and/or consumers can create them when someone else hasn't already
done so. Either way, everyone benefits!</p><p>We'd like to send a big shout-out to <a href="https://github.com/marudor" target="_blank" rel="noopener noreferrer">@marudor</a> for
contributing so many of his own libdefs and spending time helping others to
write and contribute libdefs. Additionally we'd like to thank
<a href="https://github.com/ryyppy" target="_blank" rel="noopener noreferrer">@ryyppy</a> for helping to design and iterate on the
CLI and installation workflow as well as manage libdef reviews.</p><p>The Flow core team intends to stay invested in developing and improving this
project, but in order for it to truly succeed we need your help! If you've
already written some libdefs for Flow projects that you work on, we encourage
you to <a href="https://github.com/flowtype/flow-typed/#how-do-i-contribute-library-definitions" target="_blank" rel="noopener noreferrer">contribute</a>
them for others to benefit from them as well. By managing libdefs in a
community-driven repository, the community as a whole can work together to
extend Flow's capabilities beyond just explicitly-typed JS.</p><p>It's still early days and there's still a lot to do, so we're excited to hear
your ideas/feedback and read your pull requests! :)</p><p>Happy typing!</p>]]></content>
        <author>
            <name>Jeff Morrison</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Property Variance and Other Upcoming Changes]]></title>
        <id>https://flow.org/blog/2016/10/04/Property-Variance</id>
        <link href="https://flow.org/blog/2016/10/04/Property-Variance"/>
        <updated>2016-10-04T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[The next release of Flow, 0.34, will include a few important changes to object]]></summary>
        <content type="html"><![CDATA[<p>The next release of Flow, 0.34, will include a few important changes to object
types:</p><ul><li>property variance,</li><li>invariant-by-default dictionary types,</li><li>covariant-by-default method types,</li><li>and more flexible getters and setters.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-variance">What is Variance?<a href="#what-is-variance" class="hash-link" aria-label="Direct link to What is Variance?" title="Direct link to What is Variance?">​</a></h3><p>Defining the subtype relationship between types is a core responsibility of Flow
as a type system. These relationships are determined either directly for
simple types or, for complex types, defined in terms of their parts.</p><p>Variance describes the subtyping relationship for complex types as it relates
to the subtyping relationships of their parts.</p><p>For example, Flow directly encodes the knowledge that <code>string</code> is a subtype of
<code>?string</code>. Intuitively, a <code>string</code> type contains string values while a <code>?string</code>
type contains <code>null</code>, <code>undefined</code>, and also string values, so membership in the
former naturally implies membership in the later.</p><p>The subtype relationships between two function types is not as direct. Rather,
it is derived from the subtype relationships between the functions' parameter
and return types.</p><p>Let's see how this works for two simple function types:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name constant" style="color:#36acaa">F1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">P1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">R1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name constant" style="color:#36acaa">F2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">P2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">R2</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Whether <code>F2</code> is a subtype of <code>F1</code> depends on the relationships between <code>P1</code> and
<code>P2</code> and <code>R1</code> and <code>R2</code>. Let's use the notation <code>B &lt;: A</code> to mean <code>B</code> is a
subtype of <code>A</code>.</p><p>It turns out that <code>F2 &lt;: F1</code> if <code>P1 &lt;: P2</code> and <code>R2 &lt;: R1</code>. Notice that the
relationship for parameters is reversed? In technical terms, we can say that
function types are "contravariant" with respect to their parameter types and
"covariant" with respect to their return types.</p><p>Let's look at an example:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function-variable function" style="color:#d73a49">callback</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">callback</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"hi"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>What kinds of functions can we pass to <code>f</code>? Based on the subtyping rule above,
then we can pass a function whose parameter type is a supertype of <code>string</code> and
whose return type is a subtype of <code>?number</code>.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">g</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">g</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The body of <code>f</code> will only ever pass <code>string</code> values into <code>g</code>, which is safe
because <code>g</code> takes at least <code>string</code> by taking <code>?string</code>. Conversely, <code>g</code> will
only ever return <code>number</code> values to <code>f</code>, which is safe because <code>f</code> handles at
least <code>number</code> by handling <code>?number</code>.</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="input-and-output">Input and Output<a href="#input-and-output" class="hash-link" aria-label="Direct link to Input and Output" title="Direct link to Input and Output">​</a></h4><p>One convenient way to remember when something is covariant vs. contravariant is
to think about "input" and "output."</p><p>Parameters are in an <em>input</em> position, often called a "negative" position.
Complex types are contravariant in their input positions.</p><p>Return is an <em>output</em> position, often called a "positive" position. Complex
types are covariant in their output positions.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="property-invariance">Property Invariance<a href="#property-invariance" class="hash-link" aria-label="Direct link to Property Invariance" title="Direct link to Property Invariance">​</a></h2><p>Just as function types are composed of parameter and return types, so too are
object types composed of property types. Thus, the subtyping relationship
between objects is derived from the subtyping relationships of their
properties.</p><p>However, unlike functions which have input parameters and an output return,
object properties can be read and written. That is, properties are <em>both</em> input
and output.</p><p>Let's see how this works for two simple object types:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name constant" style="color:#36acaa">O1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T1</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name constant" style="color:#36acaa">O2</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">T2</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>As with function types, whether <code>O2</code> is a subtype of <code>O1</code> depends on the
relationship between its parts, <code>T1</code> and <code>T2</code>.</p><p>Here it turns out that <code>O2 &lt;: O1</code> if <code>T2 &lt;: T1</code> <em>and</em> <code>T1 &lt;: T2</code>. In technical
terms, object types are "invariant" with respect to their property types.</p><p>Let's look at an example:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">void</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// We can read p from o</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> len</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    len </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    len </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// We can also write into p</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>What kinds of objects can we pass into <code>f</code>, then? If we try to pass in an
object with a subtype property, we get an error:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o1</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {p: ?string}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^ null. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var o1: {p: string} = {p: ""};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ^ string</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {p: ?string}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^ undefined. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var o1: {p: string} = {p: ""};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">            ^ string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flow has correctly identified an error here. If the body of <code>f</code> writes <code>null</code>
into <code>o.p</code>, then <code>o1.p</code> would no longer have type <code>string</code>.</p><p>If we try to pass an object with a supertype property, we again get an error:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o2</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token punctuation" style="color:#393A34">(</span><span class="token builtin">string</span><span class="token operator" style="color:#393A34">|</span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">var o1: {p: ?(string|number)} = {p: ""};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                     ^ number. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {p: ?string}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^ string</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Again, Flow correctly identifies an error, because if <code>f</code> tried to read <code>p</code>
from <code>o</code>, it would find a number.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="property-variance">Property Variance<a href="#property-variance" class="hash-link" aria-label="Direct link to Property Variance" title="Direct link to Property Variance">​</a></h3><p>So objects have to be invariant with respect to their property types because
properties can be read from and written to. But just because you <em>can</em> read and
write, doesn't mean you always do.</p><p>Consider a function that gets the length of an nullable string property:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We never write into <code>o.p</code>, so we should be able to pass in an object where the
type of property <code>p</code> is a subtype of <code>?string</code>. Until now, this wasn't possible
in Flow.</p><p>With property variance, you can explicitly annotate object properties as being
covariant and contravariant. For example, we can rewrite the above function:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// no type error!</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>It's crucial that covariant properties only ever appear in output positions. It
is an error to write to a covariant property:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">+</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">o.p = null;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">^ object type. Covariant property `p` incompatible with contravariant use in</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">o.p = null;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">^ assignment of property `p`</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Conversely, if a function only ever writes to a property, we can annotate the
property as contravariant. This might come up in a function that initializes an
object with default values, for example.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">g</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">-</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">void</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"default"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">g</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Contravariant properties can only ever appear in input positions. It is an
error to read from a contravariant property:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token operator" style="color:#393A34">-</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">length</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">o.p.length;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">^ object type. Contravariant property `p` incompatible with covariant use in</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">o.p.length;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">^ property `p`</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="invariant-by-default-dictionary-types">Invariant-by-default Dictionary Types<a href="#invariant-by-default-dictionary-types" class="hash-link" aria-label="Direct link to Invariant-by-default Dictionary Types" title="Direct link to Invariant-by-default Dictionary Types">​</a></h3><p>The object type <code>{[key: string]: ?number}</code> describes an object that can be used
as a map. We can read any property and Flow will infer the result type as
<code>?number</code>. We can also write <code>null</code> or <code>undefined</code> or <code>number</code> into any
property.</p><p>In Flow 0.33 and earlier, these dictionary types were treated covariantly by
the type system. For example, Flow accepted the following code:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">key</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  o</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">p</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">p</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">o</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This is unsound because <code>f</code> can overwrite property <code>p</code> with <code>null</code>. In Flow
0.34, dictionaries are invariant, like named properties. The same code now
results in the following type error:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {[key: string]: ?number}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                               ^ null. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">declare var o: {p: number};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^ number</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {[key: string]: ?number}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                               ^ undefined. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">declare var o: {p: number};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^ number</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Covariant and contravariant dictionaries can be incredibly useful, though. To
support this, the same syntax used to support variance for named properties can
be used for dictionaries as well.</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function f(o: {+[key: string]: ?number}) {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">declare var o: {p: number};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">f(o); // no type error!</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="covariant-by-default-method-types">Covariant-by-default Method Types<a href="#covariant-by-default-method-types" class="hash-link" aria-label="Direct link to Covariant-by-default Method Types" title="Direct link to Covariant-by-default Method Types">​</a></h3><p>ES6 gave us a shorthand way to write object properties which are functions.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">m</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flow now interprets properties which use this shorthand method syntax as
covariant by default. This means it is an error to write to the property <code>m</code>.</p><p>If you don't want covariance, you can use the long form syntax:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function-variable function" style="color:#d73a49">m</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="more-flexible-getters-and-setters">More Flexible Getters and Setters<a href="#more-flexible-getters-and-setters" class="hash-link" aria-label="Direct link to More Flexible Getters and Setters" title="Direct link to More Flexible Getters and Setters">​</a></h3><p>In Flow 0.33 and earlier, getters and setters had to agree exactly on their
return type and parameter type, respectively. Flow 0.34 lifts that restriction.</p><p>This means you can write code like the following:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// @flow</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> o </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">x</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">set</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">x</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> value </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"default"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Sam Goldman</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Windows Support is Here!]]></title>
        <id>https://flow.org/blog/2016/08/01/Windows-Support</id>
        <link href="https://flow.org/blog/2016/08/01/Windows-Support"/>
        <updated>2016-08-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[We are excited to announce that Flow is now officially available on 64-bit]]></summary>
        <content type="html"><![CDATA[<p>We are excited to announce that Flow is now officially available on 64-bit
Windows! Starting with
<a href="https://github.com/facebook/flow/releases/tag/v0.30.0" target="_blank" rel="noopener noreferrer">Flow v0.30.0</a>, we will
publish a Windows binary with each release. You can download the Windows binary
in a .zip file directly from the
<a href="https://github.com/facebook/flow/releases" target="_blank" rel="noopener noreferrer">GitHub releases page</a> or install it
using the <a href="https://www.npmjs.com/package/flow-bin" target="_blank" rel="noopener noreferrer">flow-bin npm package</a>. Try
it out and <a href="https://github.com/facebook/flow/issues" target="_blank" rel="noopener noreferrer">report any issues</a> you
come across!</p><p>![Windows Support GIF]<!-- -->({{ site.baseurl }}/static/windows.gif)</p><p>Getting Flow working on Windows was not easy, and it was made possible by the
hard work of <a href="https://github.com/OCamlPro-Henry" target="_blank" rel="noopener noreferrer">Grégoire</a>,
<a href="https://github.com/OCamlPro-Bozman" target="_blank" rel="noopener noreferrer">Çagdas</a> and
<a href="https://github.com/lefessan" target="_blank" rel="noopener noreferrer">Fabrice</a> from
<a href="https://www.ocamlpro.com/" target="_blank" rel="noopener noreferrer">OCamlPro</a>.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started-with-windows">Getting Started with Windows<a href="#getting-started-with-windows" class="hash-link" aria-label="Direct link to Getting Started with Windows" title="Direct link to Getting Started with Windows">​</a></h3><h4 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started-with-flow-bin-on-windows">Getting Started with flow-bin on Windows<a href="#getting-started-with-flow-bin-on-windows" class="hash-link" aria-label="Direct link to Getting Started with flow-bin on Windows" title="Direct link to Getting Started with flow-bin on Windows">​</a></h4><p>Does your JavaScript project use npm to manage dependencies? Well, then the
easiest way for you to install Flow is with npm! Just run</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> --save-dev flow-bin</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>(Note: on Windows, it is recommended to use npm v3, to avoid the long
<code>node_modules</code> paths that npm v2 creates)</p><p>This will install the
<a href="https://www.npmjs.com/package/flow-bin" target="_blank" rel="noopener noreferrer">flow-bin npm package</a> and
automatically add it to your package.json. Once installed, there are a few ways
to use the Flow binary. One is to use <code>./node_modules/.bin/flow</code> directly. For
example, every Flow project needs a <code>.flowconfig</code> file in the root directory.
If you don't already have a <code>.flowconfig</code>, you could create it with Powershell,
like</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> New-Item .flowconfig</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>or you could run the <code>flow init</code> command, using <code>./node_modules/.bin/flow</code></p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> ./node_modules/.bin/flow init</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Another way to run Flow is via an npm script. In your package.json file, there
is a <code>"scripts"</code> section. Maybe it looks like this:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token string-property property" style="color:#36acaa">"scripts"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string-property property" style="color:#36acaa">"test"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"make test"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>You can run the Flow binary directly from a script by referencing <code>flow</code> in a
script, like so:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token string-property property" style="color:#36acaa">"scripts"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string-property property" style="color:#36acaa">"test"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"make test"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token string-property property" style="color:#36acaa">"flow_check"</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"flow check || exit 0"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>and then running that script via <code>npm run</code></p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> run flow_check</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>(Note: the <code>|| exit 0</code> part of the script is optional, but <code>npm run</code> will show
an error message if the script finishes with a non-zero exit code)</p><p>You can also install <code>flow-bin</code> globally with</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> --global flow-bin</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="getting-started-with-flowexe">Getting Started with flow.exe<a href="#getting-started-with-flowexe" class="hash-link" aria-label="Direct link to Getting Started with flow.exe" title="Direct link to Getting Started with flow.exe">​</a></h4><p>Each <a href="https://github.com/facebook/flow/releases" target="_blank" rel="noopener noreferrer">GitHub release of Flow</a>
starting with v0.30.0 will have a zipped Windows binary. For example, the
<a href="https://github.com/facebook/flow/releases/tag/v0.30.0" target="_blank" rel="noopener noreferrer">v0.30.0 release</a>
includes <a href="https://github.com/facebook/flow/releases/download/v0.30.0/flow-win64-v0.30.0.zip" target="_blank" rel="noopener noreferrer">flow-win64-v0.30.0.zip</a>.
If you download and unzip that, you will find a <code>flow/</code> directory, which
contains <code>flow.exe</code>. <code>flow.exe</code> is the Flow binary, so if you put that
somewhere in your path, and you should be good to go.</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">mkdir</span><span class="token plain"> demo</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token builtin class-name">cd</span><span class="token plain"> demo</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> flow.exe init</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/* @flow */ var x: number = true;"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> Out-File -Encoding ascii test.js</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> flow.exe check</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">test.js:1</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token number" style="color:#36acaa">1</span><span class="token plain">: /* @flow */ var x: number </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                                 ^^^^ boolean. This </span><span class="token builtin class-name">type</span><span class="token plain"> is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token number" style="color:#36acaa">1</span><span class="token plain">: /* @flow */ var x: number </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                        ^^^^^^ number</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[New Implementation of Unions and Intersections]]></title>
        <id>https://flow.org/blog/2016/07/01/New-Unions-Intersections</id>
        <link href="https://flow.org/blog/2016/07/01/New-Unions-Intersections"/>
        <updated>2016-07-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Summary]]></summary>
        <content type="html"><![CDATA[<h3 class="anchor anchorWithStickyNavbar_LWe7" id="summary">Summary<a href="#summary" class="hash-link" aria-label="Direct link to Summary" title="Direct link to Summary">​</a></h3><p>Before Flow 0.28, the implementation of union/intersection types had serious
bugs and was <a href="https://github.com/facebook/flow/issues/1759" target="_blank" rel="noopener noreferrer">the</a> <a href="https://github.com/facebook/flow/issues/1664" target="_blank" rel="noopener noreferrer">root</a> <a href="https://github.com/facebook/flow/issues/1663" target="_blank" rel="noopener noreferrer">cause</a> <a href="https://github.com/facebook/flow/issues/1462" target="_blank" rel="noopener noreferrer">of</a>
<a href="https://github.com/facebook/flow/issues/1455" target="_blank" rel="noopener noreferrer">a</a> <a href="https://github.com/facebook/flow/issues/1371" target="_blank" rel="noopener noreferrer">lot</a> <a href="https://github.com/facebook/flow/issues/1349" target="_blank" rel="noopener noreferrer">of</a> <a href="https://github.com/facebook/flow/issues/824" target="_blank" rel="noopener noreferrer">weird</a> <a href="https://github.com/facebook/flow/issues/815" target="_blank" rel="noopener noreferrer">behaviors</a> you
may have run into with Flow in the past. These bugs have now been addressed in
<a href="https://github.com/facebook/flow/commit/2df7671e7bda770b95e6b1eaede96d7a8ab1f2ac" target="_blank" rel="noopener noreferrer">a diff landing in 0.28</a>.</p><p>As you might expect after a major rewrite of a tricky part of the type system
implementation, there will be a short period of adjustment: you may run into
kinks that we will try to iron out promptly, and you may run into some
unfamiliar error messages.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-error-messages">New Error Messages<a href="#new-error-messages" class="hash-link" aria-label="Direct link to New Error Messages" title="Direct link to New Error Messages">​</a></h3><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">&lt;error location&gt; Could not decide which case to select</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">&lt;location of union/intersection type&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Case 1 may work:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  &lt;location of 1st case of union/intersection type&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  But if it doesn't, case 2 looks promising too:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  &lt;location of 2nd case of union/intersection type&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  Please provide additional annotation(s) to determine whether case 1 works</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  (or consider merging it with case 2):</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  &lt;location to annotate&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  &lt;location to annotate&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ...</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>What this means is that at <code>&lt;error location&gt;</code>, Flow needs to make a choice: one
of the members of the union/intersection type at
<code>&lt;location of union/intersection type&gt;</code> must be applied, but Flow can't choose
safely based on available information. In particular, it cannot decide between
case <code>1</code> and <code>2</code>, so Flow lists a bunch of annotations that can help it
disambiguate the two cases.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="actions-needed">Actions Needed<a href="#actions-needed" class="hash-link" aria-label="Direct link to Actions Needed" title="Direct link to Actions Needed">​</a></h3><p>You can fix the errors in two ways:</p><ul><li>Actually go and annotate the listed locations. This should be by far the most
common fix.</li><li>Discover that there is real, unintentional ambiguity between case 1 and 2,
and rewrite the two cases in the union type to remove the ambiguity. When
this happens, typically it will fix a large number of errors.</li></ul><p>There are two more possibilities, however:</p><ul><li>There's no real ambiguity and Flow is being too conservative / dumb. In this
case, go ahead and do the annotations anyway and file an issue on GitHub. We
plan to do a lot of short-term follow-up work to disambiguate more cases
automatically, so over time you should see less of (3).</li><li>You have no idea what's going on. The cases being pointed to don't make sense.
They don't correspond to what you have at <code>&lt;error location&gt;</code>. Hopefully you
won't run into (4) too often, but if you do <strong>please file an issue</strong>, since
this means there are still latent bugs in the implementation.</li></ul><p>If you file an issue on GitHub, please include code to reproduce the issue. You
can use <a href="https://flowtype.org/try/" target="_blank" rel="noopener noreferrer">Try Flow</a> to share your repro case easily.</p><p>If you're curious about the whys and hows of these new error messages, here's
an excerpt from the commit message of the "fate of the union" diff:</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="problem">Problem<a href="#problem" class="hash-link" aria-label="Direct link to Problem" title="Direct link to Problem">​</a></h3><p>Flow's inference engine is designed to find more errors over time as
constraints are added...but it is not designed to backtrack. Unfortunately,
checking the type of an expression against a union type does need backtracking:
if some branch of the union doesn't work out, the next branch must be tried,
and so on. (The same is true for checks that involve intersection types.)</p><p>The situation is further complicated by the fact that the type of the
expression may not be completely known at the point of checking, so that a
branch that looks promising now might turn out to be incorrect later.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="solution">Solution<a href="#solution" class="hash-link" aria-label="Direct link to Solution" title="Direct link to Solution">​</a></h3><p>The basic idea is to delay trying a branch until a point where we can decide
whether the branch will definitely fail or succeed, without further
information. If trying a branch results in failure, we can move on to the next
branch without needing to backtrack. If a branch succeeds, we are done. The
final case is where the branch looks promising, but we cannot be sure without
adding constraints: in this case we try other branches, and <em>bail</em> when we run
into ambiguities...requesting additional annotations to decide which branch to
select. Overall, this means that (1) we never commit to a branch that might
turn out to be incorrect and (2) can always select a correct branch (if such
exists) given enough annotations.</p>]]></content>
        <author>
            <name>Sam Goldman</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version 0.21.0]]></title>
        <id>https://flow.org/blog/2016/02/02/Version-0.21.0</id>
        <link href="https://flow.org/blog/2016/02/02/Version-0.21.0"/>
        <updated>2016-02-02T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Yesterday we deployed Flow v0.21.0! As always, we've listed out the most]]></summary>
        <content type="html"><![CDATA[<p>Yesterday we deployed Flow v0.21.0! As always, we've listed out the most
interesting changes in the
<a href="https://github.com/facebook/flow/blob/master/Changelog.md#v0210" target="_blank" rel="noopener noreferrer">Changelog</a>.
However, since I'm on a plane and can't sleep, I thought it might be fun to
dive into a couple of the changes! Hope this blog post turns out interesting
and legible!</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="jsx-intrinsics">JSX Intrinsics<a href="#jsx-intrinsics" class="hash-link" aria-label="Direct link to JSX Intrinsics" title="Direct link to JSX Intrinsics">​</a></h3><p>If you're writing JSX, it's probably a mix of your own React Components and
some intrinsics. For example, you might write</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">render</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">&lt;FluffyBunny name="Fifi" /&gt;</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In this example, <code>FluffyBunny</code> is a React Component you wrote and <code>div</code> is a
JSX intrinsic. Lower-cased JSX elements are assumed to be intrinsics by React
and by Flow. Up until Flow v0.21.0, Flow ignored intrinsics and gave them the
type <code>any</code>. This meant Flow let you set any property on JSX intrinsics. Flow
v0.21.0 will, by default, do the same thing as v0.20.0, However now you can
also configure Flow to properly type your JSX intrinsics!</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="example-of-how-to-use-jsx-intrinsics">Example of how to use JSX intrinsics<a href="#example-of-how-to-use-jsx-intrinsics" class="hash-link" aria-label="Direct link to Example of how to use JSX intrinsics" title="Direct link to Example of how to use JSX intrinsics">​</a></h4><p>.flowconfig</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">libs</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">myLib</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">js</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>myLib.js</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// JSXHelper is a type alias to make this example more concise.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// There's nothing special or magic here.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// JSXHelper&lt;{name: string}&gt; is a React component</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// with the single string property "name", which has a default</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">JSXHelper</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name constant" style="color:#36acaa">T</span><span class="token class-name operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token maybe-class-name">Class</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token maybe-class-name">ReactComponent</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">mixed</span><span class="token operator" style="color:#393A34">&gt;&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// $JSXIntrinsics is special and magic.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// This declares the types for `div` and `span`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token class-name">$JSXIntrinsics</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  div</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">JSXHelper</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  span</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">JSXHelper</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>myCode.js</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">asdf</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// No error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">id</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript number" style="color:#36acaa">42</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// Error: `id` prop is a string, not a number!</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="what-is-going-on-here">What is going on here?<a href="#what-is-going-on-here" class="hash-link" aria-label="Direct link to What is going on here?" title="Direct link to What is going on here?">​</a></h4><p>The new bit of magic is this <code>$JSXIntrinsics</code> type alias. When Flow sees
<code>&lt;foo /&gt;</code> it will look to see if <code>$JSXIntrinsics</code> exists and if so will grab
the type of <code>$JSXIntrinsics['foo']</code>. It will use this type to figure out which
properties are available and need to be set.</p><p>We haven't hardcoded the intrinsics into Flow since the available intrinsics
will depend on your environment. For example, React native would have different
intrinsics than React for the web would.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="smarter-string-refinements">Smarter string refinements<a href="#smarter-string-refinements" class="hash-link" aria-label="Direct link to Smarter string refinements" title="Direct link to Smarter string refinements">​</a></h3><p>One of the main ways that we make Flow smarter is by teaching it to recognize
more ways that JavaScript programmers refine types. Here's an example of a
common way to refine nullable values:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">Person</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token spread operator" style="color:#393A34">...</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token method function property-access" style="color:#d73a49">getName</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Before the if, this.name could be null, undefined, or a string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">name</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">null</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token comment" style="color:#999988;font-style:italic">// But now the programmer has refined this.name to definitely be a string</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">name</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// And now we know that this.name is null or undefined.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'You know who'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h4 class="anchor anchorWithStickyNavbar_LWe7" id="new-string-refinements">New string refinements<a href="#new-string-refinements" class="hash-link" aria-label="Direct link to New string refinements" title="Direct link to New string refinements">​</a></h4><p>In v0.21.0, one of the refinements we added is the ability to refine types by
comparing them to strings.</p><p>This is useful for refining unions of string literals into string literals</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'bar'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Now Flow understands that x has the type 'foo'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>And can also narrow the value of strings:</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token comment" style="color:#999988;font-style:italic">// Now Flow knows x has the type 'foo'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'foo'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This is one of the many refinements that Flow currently can recognize and
follow, and we'll keep adding more! Stay tuned!</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version-0.19.0]]></title>
        <id>https://flow.org/blog/2015/12/01/Version-0.19.0</id>
        <link href="https://flow.org/blog/2015/12/01/Version-0.19.0"/>
        <updated>2015-12-01T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow v0.19.0 was deployed today! It has a ton of changes, which the]]></summary>
        <content type="html"><![CDATA[<p>Flow v0.19.0 was deployed today! It has a ton of changes, which the
<a href="https://github.com/facebook/flow/blob/master/Changelog.md#v0190" target="_blank" rel="noopener noreferrer">Changelog</a>
summarizes. The Changelog can be a little concise, though, so here are some
longer explanations for some of the changes. Hope this helps!</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="noflow"><code>@noflow</code><a href="#noflow" class="hash-link" aria-label="Direct link to noflow" title="Direct link to noflow">​</a></h3><p>Flow is opt-in by default (you add <code>@flow</code> to a file). However we noticed that
sometimes people would add Flow annotations to files that were missing <code>@flow</code>.
Often, these people didn't notice that the file was being ignored by Flow. So
we decided to stop allowing Flow syntax in non-Flow files. This is easily fixed
by adding either <code>@flow</code> or <code>@noflow</code> to your file. The former will make the
file a Flow file. The latter will tell Flow to completely ignore the file.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="declaration-files">Declaration files<a href="#declaration-files" class="hash-link" aria-label="Direct link to Declaration files" title="Direct link to Declaration files">​</a></h3><p>Files that end with <code>.flow</code> are now treated specially. They are the preferred
provider of modules. That is if both <code>foo.js</code> and <code>foo.js.flow</code> exist, then
when you write <code>import Foo from './foo'</code>, Flow will use the type exported from
<code>foo.js.flow</code> rather than <code>foo.js</code>.</p><p>We imagine two main ways people will use <code>.flow</code> files.</p><ol><li><p>As interface files. Maybe you have some library <code>coolLibrary.js</code> that is
really hard to type with inline Flow types. You could put
<code>coolLibrary.js.flow</code> next to it and declare the types that <code>coolLibrary.js</code>
exports.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// coolLibrary.js.flow</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> coolVar</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">coolFunction</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">coolClass</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li><li><p>As the original source. Maybe you want to ship the minified, transformed
version of <code>awesomeLibrary.js</code>, but people who use <code>awesomeLibrary.js</code> also
use Flow. Well you could do something like</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cp</span><span class="token plain"> awesomeLibraryOriginalCode.js awesomeLibrary.js.flow</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">babel awesomeLibraryOriginalCode --out-file awesomeLibrary.js</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></li></ol><h3 class="anchor anchorWithStickyNavbar_LWe7" id="order-of-precedence-for-lib-files">Order of precedence for lib files<a href="#order-of-precedence-for-lib-files" class="hash-link" aria-label="Direct link to Order of precedence for lib files" title="Direct link to Order of precedence for lib files">​</a></h3><p>Now your local lib files will override the builtin lib files. Is one of the
builtin flow libs wrong? Send a pull request! But then while you're waiting for
the next release, you can use your own definition! The order of precedence is
as follows:</p><ol><li>Any paths supplied on the command line via --lib</li><li>The files found in the paths specified in the .flowconfig <code>[libs]</code> (in
listing order)</li><li>The Flow core library files</li></ol><p>For example, if I want to override the builtin definition of Array and instead
use my own version, I could update my <code>.flowconfig</code> to contain</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// .flowconfig</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[libs]</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">myArray.js</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// myArray.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">declare</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name builtin">Array</span><span class="token class-name operator" style="color:#393A34">&lt;</span><span class="token class-name constant" style="color:#36acaa">T</span><span class="token class-name operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Put whatever you like in here!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="deferred-initialization">Deferred initialization<a href="#deferred-initialization" class="hash-link" aria-label="Direct link to Deferred initialization" title="Direct link to Deferred initialization">​</a></h3><p>Previously the following code was an error, because the initialization of
<code>myString</code> happens later. Now Flow is fine with it.</p><div class="language-tsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-tsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">someFlag</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">boolean</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token builtin">string</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> myString</span><span class="token operator" style="color:#393A34">:</span><span class="token builtin">string</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">someFlag</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    myString </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"yup"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    myString </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"nope"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> myString</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Typing Generators with Flow]]></title>
        <id>https://flow.org/blog/2015/11/09/Generators</id>
        <link href="https://flow.org/blog/2015/11/09/Generators"/>
        <updated>2015-11-09T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Flow 0.14.0 included support for generator functions. Generator functions provide a unique ability to JavaScript programs: the ability to suspend and resume execution. This kind of control paves the way for async/await, an upcoming feature already supported by Flow.]]></summary>
        <content type="html"><![CDATA[<p>Flow 0.14.0 included support for generator functions. Generator functions provide a unique ability to JavaScript programs: the ability to suspend and resume execution. This kind of control paves the way for async/await, an <a href="https://github.com/tc39/ecmascript-asyncawait" target="_blank" rel="noopener noreferrer">upcoming feature</a> already supported by Flow.</p><p>So much wonderful material has already been produced describing generators. I am going to focus on the interaction of static typing with generators. Please refer to the following materials for information about generators:</p><ul><li>Jafar Husain gave an <a href="https://www.youtube.com/watch?v=DqMFX91ToLw#t=970" target="_blank" rel="noopener noreferrer">incredibly lucid and well-illustrated talk</a> that covers generators. I have linked to the point where he gets into generators, but I highly recommend the entire talk.</li><li>Exploring ES6, a comprehensive book by Axel Rauschmayer, who has generously made the contents available for free online, has a <a href="http://exploringjs.com/es6/ch_generators.html" target="_blank" rel="noopener noreferrer">chapter on generators</a>.</li><li>The venerable MDN has a <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators" target="_blank" rel="noopener noreferrer">useful page</a> describing the <code>Iterator</code> interface and generators.</li></ul><p>In Flow, the <code>Generator</code> interface has three type parameters: <code>Yield</code>, <code>Return</code>, and <code>Next</code>. <code>Yield</code> is the type of values which are yielded from the generator function. <code>Return</code> is the type of the value which is returned from the generator function. <code>Next</code> is the type of values which are passed into the generator via the <code>next</code> method on the <code>Generator</code> itself. For example, a generator value of type <code>Generator&lt;string,number,boolean&gt;</code> will yield <code>string</code>s, return a <code>number</code>, and will receive <code>boolean</code>s from its caller.</p><p>For any type <code>T</code>, a <code>Generator&lt;T,void,void&gt;</code> is both an <code>Iterable&lt;T&gt;</code> and an <code>Iterator&lt;T&gt;</code>.</p><p>The unique nature of generators allows us to represent infinite sequences naturally. Consider the infinite sequence of natural numbers:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Because generators are also iterators, we can manually iterate the generator:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 0 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 1 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 2 }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>When <code>done</code> is false, <code>value</code> will have the generator's <code>Yield</code> type. When <code>done</code> is true, <code>value</code> will have the generator's <code>Return</code> type or <code>void</code> if the consumer iterates past the completion value.</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token function" style="color:#d73a49">test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"complete"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">test</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 1 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: true, value: "complete" }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: true, value: undefined }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Because of this behavior, manually iterating poses typing difficulties. Let's try to take the first 10 values from the <code>nats</code> generator through manual iteration:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">take10</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> done</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> value </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">break</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    take10</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// error!</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">test.js:13</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> 13:   const { done, value } = gen.next();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                               ^^^^^^^^^^ call of method `next`</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> 17:     take10.push(value); // error!</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                     ^^^^^ undefined. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> 11: const take10: number[] = [];</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                   ^^^^^^ number</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flow is complaining that <code>value</code> might be <code>undefined</code>. This is because the type of <code>value</code> is <code>Yield | Return | void</code>, which simplifies in the instance of <code>nats</code> to <code>number | void</code>. We can introduce a dynamic type test to convince Flow of the invariant that <code>value</code> will always be <code>number</code> when <code>done</code> is false.</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">take10</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> done</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> value </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">done</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">break</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> value </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"undefined"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"`value` must be a number."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    take10</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">value</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// no error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>There is an <a href="https://github.com/facebook/flow/issues/577" target="_blank" rel="noopener noreferrer">open issue</a> which would make the dynamic type test above unnecessary, by using the <code>done</code> value as a sentinel to refine a tagged union. That is, when <code>done</code> is <code>true</code>, Flow would know that <code>value</code> is always of type <code>Yield</code> and otherwise of type <code>Return | void</code>.</p><p>Even without the dynamic type test, this code is quite verbose and it's hard to see the intent. Because generators are also iterable, we can also use <code>for...of</code> loops:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">take10</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> nat </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">break</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  take10</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">nat</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  i</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>That's much better. The <code>for...of</code> looping construct ignores completion values, so Flow understands that <code>nat</code> will always be <code>number</code>. Let's generalize this pattern further using generator functions:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">take</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">xs</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Iterable</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Iterable</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n </span><span class="token operator" style="color:#393A34">&lt;=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> i </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> x </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> xs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">++</span><span class="token plain">i </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> n </span><span class="token keyword" style="color:#00009f">of</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">take</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">10</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">nats</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">n</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note that we explicitly annotated the parameters and return type of the <code>take</code> generator. This is necessary to ensure Flow understands the fully generic type. This is because Flow does not currently infer a fully generic type, but instead accumulates lower bounds, resulting in a union type.</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">identity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> x </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">a</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">identity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">b</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">identity</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// error</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The above code produces errors because Flow adds <code>string</code> and <code>number</code> as lower bounds to the type variable describing the type of the value bound by <code>x</code>. That is, Flow believes the type of <code>identity</code> is <code>(x: string | number) =&gt; string | number</code> because those are the types which actually passed through the function.</p><p>Another important feature of generators is the ability to pass values into the generator from the consumer. Let's consider a generator <code>scan</code>, which reduces values passed into the generator using a provided function. Our <code>scan</code> is similar to <code>Array.prototype.reduce</code>, but it returns each intermediate value and the values are provided imperatively via <code>next</code>.</p><p>As a first pass, we might write this:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">scan</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token constant" style="color:#36acaa">U</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">init</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">f</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">acc</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter constant" style="color:#36acaa">U</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">x</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Generator</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">,</span><span class="token keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">,</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> acc </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> init</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> next </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> acc</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    acc </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">acc</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We can use this definition to implement an imperative sum procedure:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">scan</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter">b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 0 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 1 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">2</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 3 }</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">3</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// { done: false, value: 6 }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>However, when we try to check the above definition of <code>scan</code>, Flow complains:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">test.js:7</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  7:     acc = f(acc, next);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">               ^^^^^^^^^^^^ function call</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  7:     acc = f(acc, next);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">                      ^^^^ undefined. This type is incompatible with</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  3: function *scan&lt;T,U&gt;(init: U, f: (acc: U, x: T) =&gt; U): Generator&lt;U,void,T&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">     ^ some incompatible instantiation of T</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flow is complaining that our value, <code>next</code>, may be <code>void</code> instead of the expected <code>T</code>, which is <code>number</code> in the <code>sum</code> example. This behavior is necessary to ensure type safety. In order to prime the generator, our consumer must first call <code>next</code> without an argument. To accommodate this, Flow understands the argument to <code>next</code> to be optional. This means Flow will allow the following code:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> sum </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">scan</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter">b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// first call primes the generator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token console class-name">console</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">log</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">sum</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// we should pass a value, but don't need to</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In general, Flow doesn't know which invocation is "first." While it should be an error to pass a value to the first <code>next</code>, and an error to <em>not</em> pass a value to subsequent <code>next</code>s, Flow compromises and forces your generator to deal with a potentially <code>void</code> value. In short, given a generator of type <code>Generator&lt;Y,R,N&gt;</code> and a value <code>x</code> of type <code>Y</code>, the type of the expression <code>yield x</code> is <code>N | void</code>.</p><p>We can update our definition to use a dynamic type test that enforces the non-<code>void</code> invariant at runtime:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain">scan</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">,</span><span class="token constant" style="color:#36acaa">U</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">init</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">f</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">acc</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter constant" style="color:#36acaa">U</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> </span><span class="token parameter literal-property property" style="color:#36acaa">x</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter constant" style="color:#36acaa">T</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Generator</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token constant" style="color:#36acaa">U</span><span class="token punctuation" style="color:#393A34">,</span><span class="token keyword" style="color:#00009f">void</span><span class="token punctuation" style="color:#393A34">,</span><span class="token constant" style="color:#36acaa">T</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> acc </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> init</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">while</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> next </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> acc</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">typeof</span><span class="token plain"> next </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"undefined"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Error</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Caller must provide an argument to `next`."</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    acc </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">f</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">acc</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> next</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>There is one more important caveat when dealing with typed generators. Every value yielded from the generator must be described by a single type. Similarly, every value passed to the generator via <code>next</code> must be described by a single type.</p><p>Consider the following generator:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token function" style="color:#d73a49">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">foo</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">a</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// error</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">b</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// error</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This is perfectly legal JavaScript and the values <code>a</code> and <code>b</code> do have the correct types at runtime. However, Flow rejects this program. Our generator's <code>Yield</code> type parameter has a concrete type of <code>number | string</code>. The <code>value</code> property of the iterator result object has the type <code>number | string | void</code>.</p><p>We can observe similar behavior for values passed into the generator:</p><div class="codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function *bar() {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  var a = yield;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  var b = yield;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return {a,b};</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">const gen = bar();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">gen.next(); // prime the generator</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">gen.next(0);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">const ret: { a: number, b: string } = gen.next("").value; // error</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The value <code>ret</code> has the annotated type at runtime, but Flow also rejects this program. Our generator's <code>Next</code> type parameter has a concrete type of <code>number | string</code>. The <code>value</code> property of the iterator result object thus has the type <code>void | { a: void | number | string, b: void | number | string }</code>.</p><p>While it may be possible to use dynamic type tests to resolve these issues, another practical option is to use <code>any</code> to take on the type safety responsibility yourself.</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token function" style="color:#d73a49">bar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Generator</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> a </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> b </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">yield</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">a</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain">b</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> gen </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">bar</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// prime the generator</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">ret</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">void</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">a</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">b</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> gen</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">next</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">""</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// OK</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>(Note that the annotation <code>Generator</code> is equivalent to <code>Generator&lt;any,any,any&gt;</code>.)</p><p>Phew! I hope that this will help you use generators in your own code. I also hope this gave you a little insight into the difficulties of applying static analysis to a highly dynamic language such as JavaScript.</p><p>To summarize, here are some of the lessons we've learned for using generators in statically typed JS:</p><ul><li>Use generators to implement custom iterables.</li><li>Use dynamic type tests to unpack the optional return type of yield expressions.</li><li>Avoid generators that yield or receive values of multiple types, or use <code>any</code>.</li></ul>]]></content>
        <author>
            <name>Sam Goldman</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version-0.17.0]]></title>
        <id>https://flow.org/blog/2015/10/07/Version-0.17.0</id>
        <link href="https://flow.org/blog/2015/10/07/Version-0.17.0"/>
        <updated>2015-10-07T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we released Flow v0.17.0! The first thing you may notice is that we changed the way we display errors at the command line. The new errors look like this:]]></summary>
        <content type="html"><![CDATA[<p>Today we released Flow v0.17.0! The first thing you may notice is that we changed the way we display errors at the command line. The new errors look like this:</p><p>![New error format]<!-- -->({{ site.baseurl }}/static/new_error_format_v0_17_0.png)</p><p>This should hopefully help our command line users understand many errors without having to refer to their source code. We'll keep iterating on this format, so tell us what you like and what you don't like! Thanks to <a href="https://github.com/frantic" target="_blank" rel="noopener noreferrer">@frantic</a> for building this feature!</p><p>There are a whole bunch of other features and fixes in this release! Head on over to our <a href="https://github.com/facebook/flow/releases/tag/v0.17.0" target="_blank" rel="noopener noreferrer">Release</a> for the full list!</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version-0.16.0]]></title>
        <id>https://flow.org/blog/2015/09/22/Version-0.16.0</id>
        <link href="https://flow.org/blog/2015/09/22/Version-0.16.0"/>
        <updated>2015-09-22T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[On Friday we released Flow v0.16.0! We had some major perf improvements that we wanted to get into a release, plus let/const support was ready (thanks again @samwgoldman)!]]></summary>
        <content type="html"><![CDATA[<p>On Friday we released Flow v0.16.0! We had some major perf improvements that we wanted to get into a release, plus let/const support was ready (thanks again <a href="https://github.com/samwgoldman" target="_blank" rel="noopener noreferrer">@samwgoldman</a>)!</p><p>As always, the <a href="https://github.com/facebook/flow/blob/master/Changelog.md#v0160" target="_blank" rel="noopener noreferrer">Changelog</a> is best at summing up the big changes.</p>]]></content>
        <author>
            <name>Jeff Morrison</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version-0.15.0]]></title>
        <id>https://flow.org/blog/2015/09/10/Version-0.15.0</id>
        <link href="https://flow.org/blog/2015/09/10/Version-0.15.0"/>
        <updated>2015-09-10T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Today we released Flow v0.15.0! A lot has changed in the last month and we're excited to get the hard work of all our contributors in front of people! Big thanks to everyone who contributed to this release!]]></summary>
        <content type="html"><![CDATA[<p>Today we released Flow v0.15.0! A lot has changed in the last month and we're excited to get the hard work of all our contributors in front of people! Big thanks to everyone who contributed to this release!</p><p>Check out the <a href="https://github.com/facebook/flow/blob/master/Changelog.md#v0150" target="_blank" rel="noopener noreferrer">Changelog</a> to see what's new.</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Version-0.14.0]]></title>
        <id>https://flow.org/blog/2015/07/29/Version-0.14.0</id>
        <link href="https://flow.org/blog/2015/07/29/Version-0.14.0"/>
        <updated>2015-07-29T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[It has come to our attention that not everyone obsessively checks GitHub for Flow releases. This came as a surprise, but we would like to support these users too. Therefore, we will start announcing each Flow release on the blog, starting with this release.]]></summary>
        <content type="html"><![CDATA[<p>It has come to our attention that not everyone obsessively checks GitHub for Flow releases. This came as a surprise, but we would like to support these users too. Therefore, we will start announcing each Flow release on the blog, starting with this release.</p><p>So here is Flow v0.14.0! Check out the <a href="https://github.com/facebook/flow/blob/master/Changelog.md#v0140" target="_blank" rel="noopener noreferrer">Changelog</a> for the canonical list of what has changed.</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Disjoint Unions]]></title>
        <id>https://flow.org/blog/2015/07/03/Disjoint-Unions</id>
        <link href="https://flow.org/blog/2015/07/03/Disjoint-Unions"/>
        <updated>2015-07-03T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[Sometimes programs need to deal with different kinds of data all at once, where the shape of the data can be different based on what kind of data the code is looking at. This kind of programming is so common in functional programming languages that almost all such languages come with a way of:]]></summary>
        <content type="html"><![CDATA[<p>Sometimes programs need to deal with different kinds of data all at once, where the shape of the data can be different based on what kind of data the code is looking at. This kind of programming is so common in functional programming languages that almost all such languages come with a way of:</p><ul><li>Specifying such data by a set of disjoint cases, distinguished by “tags”, where each tag is associated with a different “record” of properties. (These descriptions are called “disjoint union” or “variant” types.)</li><li>Doing case analysis on such data, by checking tags and then directly accessing the associated record of properties. (The common way to do such case analysis is by pattern matching.)</li></ul><p>Examples of programs that analyze or transform such data range from compilers working with abstract syntax trees, to operations that may return exceptional values,  with much more in between!</p><p>As of Flow 0.13.1 it is now possible to program in this style in JavaScript in a type-safe manner. You can define a disjoint union of object types and do case analysis on objects of that type by switching on the value of some common property (called a "sentinel") in those object types.</p><p>Flow's syntax for disjoint unions looks like:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">type </span><span class="token maybe-class-name">BinaryTree</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">kind</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"leaf"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">value</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">kind</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"branch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">left</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">BinaryTree</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">right</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">BinaryTree</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumLeaves</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">tree</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">BinaryTree</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tree</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">kind</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"leaf"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> tree</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">value</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumLeaves</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tree</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">left</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sumLeaves</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">tree</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">right</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem">The problem<a href="#the-problem" class="hash-link" aria-label="Direct link to The problem" title="Direct link to The problem">​</a></h2><p>Consider the following function that returns different objects depending on the data passed into it:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">type </span><span class="token maybe-class-name">Result</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">status</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> errorCode</span><span class="token operator" style="color:#393A34">?</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getResult</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">op</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">Result</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">var</span><span class="token plain"> statusCode </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">op</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">statusCode </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">status</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'done'</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">status</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'error'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">errorCode</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> statusCode </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>The result contains a <code>status</code> property that is either <code>'done'</code> or <code>'error'</code>,
and an optional <code>errorCode</code> property that holds a numeric status code when the
<code>status</code> is <code>'error'</code>.</p><p>One may now try to write another function that gets the error code from a result:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getErrorCode</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">result</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">Result</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> number </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">switch</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">status</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">case</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'error'</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> result</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">errorCode</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword module" style="color:#00009f">default</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Unfortunately, this code does not typecheck. The <code>Result</code> type does not precisely
capture the relationship between the <code>status</code> property and the <code>errorCode</code> property.
Namely it doesn't capture that when the <code>status</code> property is <code>'error'</code>, the <code>errorCode</code>
property will be present and defined on the object. As a result, Flow thinks that
<code>result.errorCode</code> in the above function may return <code>undefined</code> instead of <code>number</code>.</p><p>Prior to version 0.13.1 there was no way to express this relationship, which meant
that it was not possible to check the type safety of this simple, familiar idiom!</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-solution">The solution<a href="#the-solution" class="hash-link" aria-label="Direct link to The solution" title="Direct link to The solution">​</a></h2><p>As of version 0.13.1 it is possible to write a more precise type for <code>Result</code>
that better captures the intent and helps Flow narrow down the possible shapes
of an object based on the outcome of a dynamic <code>===</code> check. Now, we can write:</p><div class="language-javaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">type Result = Done | Error</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">type Done = { status: 'done' }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">type Error = { status: 'error', errorCode: number }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>In other words, we can explicitly list out the possible shapes of results. These
cases are distinguished by the value of the <code>status</code> property. Note that here
we use the string literal types <code>'done'</code> and <code>'error'</code>. These match exactly the strings
<code>'done'</code> and <code>'error'</code>, which means that <code>===</code> checks on those values are enough for
Flow to narrow down the corresponding type cases. With this additional reasoning, the
function <code>getErrorCode</code> now typechecks, without needing any changes to the code!</p><p>In addition to string literals, Flow also supports number literals as singleton types
so they can also be used in disjoint unions and case analyses.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-we-built-this">Why we built this<a href="#why-we-built-this" class="hash-link" aria-label="Direct link to Why we built this" title="Direct link to Why we built this">​</a></h2><p>Disjoint unions are at the heart of several good programming practices pervasive in functional programming languages. Supporting them in Flow means that JavaScript can use these practices in a type-safe manner. For example, disjoint unions can be used to write type-safe <a href="https://facebook.github.io/flux/docs/dispatcher.html" target="_blank" rel="noopener noreferrer">Flux dispatchers</a>. They are also heavily used in a recently released <a href="https://github.com/graphql/graphql-js" target="_blank" rel="noopener noreferrer">reference implementation of GraphQL</a>.</p>]]></content>
        <author>
            <name>Avik Chaudhuri</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Bounded Polymorphism]]></title>
        <id>https://flow.org/blog/2015/03/12/Bounded-Polymorphism</id>
        <link href="https://flow.org/blog/2015/03/12/Bounded-Polymorphism"/>
        <updated>2015-03-12T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As of Flow 0.5.0, you can define polymorphic functions and classes with bounds on their type parameters. This is extremely useful for writing functions and classes that need some constraints on their type parameters. Flow's bounded polymorphism syntax looks like]]></summary>
        <content type="html"><![CDATA[<p>As of Flow 0.5.0, you can define polymorphic functions and classes with bounds on their type parameters. This is extremely useful for writing functions and classes that need some constraints on their type parameters. Flow's bounded polymorphism syntax looks like</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">class BagOfBones&lt;T: Bone&gt; { ... }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function eat&lt;T: Food&gt;(meal: T): Indigestion&lt;T&gt; { ... }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-problem">The problem<a href="#the-problem" class="hash-link" aria-label="Direct link to The problem" title="Direct link to The problem">​</a></h2><p>Consider the following code that defines a polymorphic function in Flow:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function fooBad&lt;T&gt;(obj: T): T {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  console.log(Math.abs(obj.x));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return obj;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This code does not (and should not!) type check. Not all values <code>obj: T</code> have a property <code>x</code>, let alone a property <code>x</code> that is a <code>number</code>, given the additional requirement imposed by <code>Math.abs()</code>.</p><p>But what if you wanted <code>T</code> to not range over all types, but instead over only the types of objects with an <code>x</code> property that has the type <code>number</code>? Intuitively, given that condition, the body should type check. Unfortunately, the only way you could enforce this condition prior to Flow 0.5.0 was by giving up on polymorphism entirely! For example you could write:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// Old lame workaround</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">function fooStillBad(obj: { x: number }): {x: number } {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  console.log(Math.abs(obj.x));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return obj;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>But while this change would make the body type check, it would cause Flow to lose information across call sites. For example:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// The return type of fooStillBad() is {x: number}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// so Flow thinks result has the type {x: number}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var result = fooStillBad({x: 42, y: "oops"});</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// This will be an error since result's type</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// doesn't have a property "y"</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var test: {x: number; y: string} = result;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-solution">The solution<a href="#the-solution" class="hash-link" aria-label="Direct link to The solution" title="Direct link to The solution">​</a></h2><p>As of version 0.5.0, such typing problems can be solved elegantly using bounded polymorphism. Type parameters such as <code>T</code> can specify bounds that constrain the types that the type parameters range over. For example, we can write:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function fooGood&lt;T: { x: number }&gt;(obj: T): T {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  console.log(Math.abs(obj.x));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return obj;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Now the body type checks under the assumption that <code>T</code> is a subtype of <code>{ x: number }</code>. Furthermore, no information is lost across call sites. Using the example from above:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// With bounded polymorphism, Flow knows the return</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// type is {x: number; y: string}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var result = fooGood({x: 42, y: "yay"});</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// This works!</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var test: {x: number; y: string} = result;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Of course, polymorphic classes may also specify bounds. For example, the following code type checks:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">class Store&lt;T: { x: number }&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  obj: T;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  constructor(obj: T) { this.obj = obj; }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  foo() { console.log(Math.abs(this.obj.x)); }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Instantiations of the class are appropriately constrained. If you write</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">var store = new Store({x: 42, y: "hi"});</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Then <code>store.obj</code> has type <code>{x: number; y: string}</code>.</p><p>Any type may be used as a type parameter's bound. The type does not need to be an object type (as in the examples above). It may even be another type parameter that is in scope. For example, consider adding the following method to the above <code>Store</code> class:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">class Store&lt;T: { x: number }&gt; {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  bar&lt;U: T&gt;(obj: U): U {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    this.obj = obj;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    console.log(Math.abs(obj.x));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">    return obj;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  }</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Since <code>U</code> is a subtype of <code>T</code>, the method body type checks (as you may expect, <code>U</code> must also satisfy <code>T</code>'s bound, by transitivity of subtyping). Now the following code type checks:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">  // store is a Store&lt;{x: number; y: string}&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  var store = new Store({x: 42, y: "yay"});</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  var result = store.bar({x: 0, y: "hello", z: "world"});</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  // This works!</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  var test: {x: number; y: string; z: string } = result;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Also, in a polymorphic definition with multiple type parameters, any type parameter may appear in the bound of any following type parameter. This is useful for type checking examples like the following:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function copyArray&lt;T, S: T&gt;(from: Array&lt;S&gt;, to: Array&lt;T&gt;) {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  from.forEach(elem =&gt; to.push(elem));</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="why-we-built-this">Why we built this<a href="#why-we-built-this" class="hash-link" aria-label="Direct link to Why we built this" title="Direct link to Why we built this">​</a></h2><p>The addition of bounded polymorphism significantly increases the expressiveness of Flow's type system, by enabling signatures and definitions to specify relationships between their type parameters, without having to sacrifice the benefits of generics. We expect that the increased expressiveness will be particularly useful to library writers, and will also allow us to write better declarations for framework APIs such as those provided by React.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="transformations">Transformations<a href="#transformations" class="hash-link" aria-label="Direct link to Transformations" title="Direct link to Transformations">​</a></h2><p>Like type annotations and other Flow features, polymorphic function and class definitions need to be transformed before the code can be run. The transforms are available in react-tools <code>0.13.0</code>, which was recently released</p>]]></content>
        <author>
            <name>Avik Chaudhuri</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Flow Comments]]></title>
        <id>https://flow.org/blog/2015/02/20/Flow-Comments</id>
        <link href="https://flow.org/blog/2015/02/20/Flow-Comments"/>
        <updated>2015-02-20T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As of Flow 0.4.0, you can put your Flow-specific syntax in special comments. If you use these special comments then you do not need to transform away Flow-specific syntax before running your code. While we strongly recommend that you write your code without the special comments, this feature will help people who can't fit a Flow-stripping transformation into their setup. This was one of our most requested features and hopefully it will enable even more people to use Flow!]]></summary>
        <content type="html"><![CDATA[<p>As of Flow 0.4.0, you can put your Flow-specific syntax in special comments. If you use these special comments then you do not need to transform away Flow-specific syntax before running your code. While we strongly recommend that you write your code without the special comments, this feature will help people who can't fit a Flow-stripping transformation into their setup. This was one of our <a href="https://github.com/facebook/flow/issues/3" target="_blank" rel="noopener noreferrer">most requested features</a> and hopefully it will enable even more people to use Flow!</p><p>This feature introduces 3 special comments: <code>/*:</code>, <code>/*::</code>, and <code>/*flow-include</code>. Flow will read the code inside these special comments and treat the code as if the special comment tokens didn't exist. These special comments are valid JavaScript block comments, so your JavaScript engine will ignore the code inside the comments.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="the-flow-comment-syntax">The Flow Comment Syntax<a href="#the-flow-comment-syntax" class="hash-link" aria-label="Direct link to The Flow Comment Syntax" title="Direct link to The Flow Comment Syntax">​</a></h2><p>There are 3 special comments that Flow currently supports. You may recognize this syntax from <a href="https://github.com/jareware" target="_blank" rel="noopener noreferrer">Jarno Rantanen</a>'s excellent project, <a href="https://github.com/jareware/flotate" target="_blank" rel="noopener noreferrer">flotate</a>.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="1-">1. <code>/*:</code><a href="#1-" class="hash-link" aria-label="Direct link to 1-" title="Direct link to 1-">​</a></h3><p><code>/*: &lt;your code&gt; */</code> is interpreted by Flow as <code>: &lt;your code&gt;</code></p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function foo(x/*: number*/)/* : string */ { ... }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>is interpreted by Flow as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function foo(x: number): string { ... }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>but appears to the JavaScript engine (ignoring comments) as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">function foo(x) { ... }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="2-">2. <code>/*::</code><a href="#2-" class="hash-link" aria-label="Direct link to 2-" title="Direct link to 2-">​</a></h3><p><code>/*:: &lt;your code&gt; */</code> is interpreted by Flow as <code>&lt;your code&gt;</code></p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">/*:: type foo = number; */</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>is interpreted by Flow as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">type foo = number;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>but appears to the runtime (ignoring comments) as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="3-flow-include">3. <code>/*flow-include</code><a href="#3-flow-include" class="hash-link" aria-label="Direct link to 3-flow-include" title="Direct link to 3-flow-include">​</a></h3><p><code>/*flow-include &lt;your code&gt; */</code> is interpreted by Flow as <code>&lt;your code&gt;</code>. It behaves the same as <code>/*::</code></p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">/*flow-include type foo = number; */</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>is interpreted by Flow as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">type foo = number;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>but appears to the runtime (ignoring comments) as</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note: whitespace is ignored after the <code>/*</code> but before the <code>:</code>, <code>::</code>, or <code>flow-include</code>. So you can write things like</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">/* : number */</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">/* :: type foo = number */</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">/* flow-include type foo = number */</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="future-work">Future Work<a href="#future-work" class="hash-link" aria-label="Direct link to Future Work" title="Direct link to Future Work">​</a></h2><p>We plan to update our Flow transformation to wrap Flow syntax with these special comments, rather than stripping it away completely. This will help people write Flow code but publish code that works with or without Flow.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="thanks">Thanks<a href="#thanks" class="hash-link" aria-label="Direct link to Thanks" title="Direct link to Thanks">​</a></h2><p>Special thanks to <a href="https://github.com/jareware" target="_blank" rel="noopener noreferrer">Jarno Rantanen</a> for building <a href="https://github.com/jareware/flotate" target="_blank" rel="noopener noreferrer">flotate</a> and supporting us merging his syntax upstream into Flow.</p>]]></content>
        <author>
            <name>Gabe Levi</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Import Type]]></title>
        <id>https://flow.org/blog/2015/02/18/Import-Types</id>
        <link href="https://flow.org/blog/2015/02/18/Import-Types"/>
        <updated>2015-02-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As of Flow 0.3.0, it's now possible to import types from another module. So, for example, if you're only importing a class for purposes of referencing it in a type annotation, you can now use the new import type syntax to do this.]]></summary>
        <content type="html"><![CDATA[<p>As of Flow 0.3.0, it's now possible to import types from another module. So, for example, if you're only importing a class for purposes of referencing it in a type annotation, you can now use the new <code>import type</code> syntax to do this.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="motivation">Motivation<a href="#motivation" class="hash-link" aria-label="Direct link to Motivation" title="Direct link to Motivation">​</a></h2><p>Has this ever happened to you:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// @flow</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Post-transformation lint error: Unused variable 'URI'</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import URI from "URI";</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// But if you delete the require you get a Flow error:</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// identifier URI - Unknown global name</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module.exports = function(x: URI): URI {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return x;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Now you have an out! To solve this problem (and with an eye toward a near future with ES6 module syntax), we've added the new <code>import type</code> syntax.  With <code>import type</code>, you can convey what you really mean here — that you want to import the <em>type</em> of the class and not really the class itself.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="enter-import-type">Enter Import Type<a href="#enter-import-type" class="hash-link" aria-label="Direct link to Enter Import Type" title="Direct link to Enter Import Type">​</a></h2><p>So instead of the above code, you can now write this:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// @flow</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import type URI from 'URI';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module.exports = function(x: URI): URI {</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  return x;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">};</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>If you have a module that exports multiple classes (like, say, a Crayon and a Marker class), you can import the type for each of them together or separately like this:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">// @flow</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">import type {Crayon, Marker} from 'WritingUtensils';</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">module.exports = function junkDrawer(x: Crayon, y: Marker): void {}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="transformations">Transformations<a href="#transformations" class="hash-link" aria-label="Direct link to Transformations" title="Direct link to Transformations">​</a></h2><p>Like type annotations and other Flow features, <code>import type</code> need to be transformed away before the code can be run. The transforms will be available in react-tools <code>0.13.0</code> when it is published soon, but for now they're available in <code>0.13.0-beta.2</code>, which you can install with</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> react-tools@0.13.0-beta.2</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="anticipatory-qa">Anticipatory Q&amp;A<a href="#anticipatory-qa" class="hash-link" aria-label="Direct link to Anticipatory Q&amp;A" title="Direct link to Anticipatory Q&amp;A">​</a></h2><h3 class="anchor anchorWithStickyNavbar_LWe7" id="wait-but-what-happens-at-runtime-after-ive-added-an-import-type-declaration">Wait, but what happens at runtime after I've added an <code>import type</code> declaration?<a href="#wait-but-what-happens-at-runtime-after-ive-added-an-import-type-declaration" class="hash-link" aria-label="Direct link to wait-but-what-happens-at-runtime-after-ive-added-an-import-type-declaration" title="Direct link to wait-but-what-happens-at-runtime-after-ive-added-an-import-type-declaration">​</a></h3><p><em>Nothing! All <code>import type</code> declarations get stripped away just like other flow syntax.</em></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="can-i-use-import-type-to-pull-in-type-aliases-from-another-module-too">Can I use <code>import type</code> to pull in type aliases from another module, too?<a href="#can-i-use-import-type-to-pull-in-type-aliases-from-another-module-too" class="hash-link" aria-label="Direct link to can-i-use-import-type-to-pull-in-type-aliases-from-another-module-too" title="Direct link to can-i-use-import-type-to-pull-in-type-aliases-from-another-module-too">​</a></h3><del>Not quite yet...but soon! There are a few other moving parts that we need to build first, but we're working on it.</del><p>EDIT: Yes! As of Flow 0.10 you can use the <code>export type MyType = ... ;</code> syntax to compliment the <code>import type</code> syntax. Here's a trivial example:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// @flow</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// MyTypes.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> type </span><span class="token maybe-class-name">UserID</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> number</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> type </span><span class="token maybe-class-name">User</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">UserID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">firstName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">lastName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> string</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// @flow</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// User.js</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> type </span><span class="token punctuation" style="color:#393A34">{</span><span class="token maybe-class-name">UserID</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"MyTypes"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">getUserID</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter literal-property property" style="color:#36acaa">user</span><span class="token parameter operator" style="color:#393A34">:</span><span class="token parameter"> </span><span class="token parameter maybe-class-name">User</span><span class="token punctuation" style="color:#393A34">)</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">UserID</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> user</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">id</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note that we only support the explicit named-export statements for now (i.e. <code>export type UserID = number;</code>). In a future version we can add support for latent named-export statements (i.e. <code>type UserID = number; export {UserID};</code>) and default type exports (i.e.  <code>export default type MyType = ... ;</code>)...but for now these forms aren't yet supported for type exports.</p>]]></content>
        <author>
            <name>Jeff Morrison</name>
        </author>
    </entry>
    <entry>
        <title type="html"><![CDATA[Announcing Typecasts]]></title>
        <id>https://flow.org/blog/2015/02/18/Typecasts</id>
        <link href="https://flow.org/blog/2015/02/18/Typecasts"/>
        <updated>2015-02-18T00:00:00.000Z</updated>
        <summary type="html"><![CDATA[As of version 0.3.0, Flow supports typecast expression.]]></summary>
        <content type="html"><![CDATA[<p>As of version 0.3.0, Flow supports typecast expression.</p><p>A typecast expression is a simple way to type-annotate any JavaScript expression. Here are some examples of typecasts:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">(1 + 1 : number);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var a = { name: (null: ?string) };</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">([1, 'a', true]: Array&lt;mixed&gt;).map(fn);</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>For any JavaScript expression <code>&lt;expr&gt;</code> and any Flow type <code>&lt;type&gt;</code>, you can write</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">(&lt;expr&gt; : &lt;type&gt;)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>Note:</strong> the parentheses are necessary.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="how-typecasts-work">How Typecasts Work<a href="#how-typecasts-work" class="hash-link" aria-label="Direct link to How Typecasts Work" title="Direct link to How Typecasts Work">​</a></h2><p>To evaluate a typecast expression, Flow will first check that <code>&lt;expr&gt;</code> is a <code>&lt;type&gt;</code>.</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">(1+1: number); // this is fine</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(1+1: string); // but this is is an error</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Second, Flow will infer that the typecast expression <code>(&lt;expr&gt;: &lt;type&gt;)</code> has the type <code>&lt;type&gt;</code>.</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">[(0: ?number)]; // Flow will infer the type Array&lt;?number&gt;</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">[0];            // Without the typecast, Flow infers the type Array&lt;number&gt;</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="safety">Safety<a href="#safety" class="hash-link" aria-label="Direct link to Safety" title="Direct link to Safety">​</a></h2><p>Typecasts obey the same rules as other type annotations, so they provide the same safety guarantees. This means they are safe unless you explicitly use the <code>any</code> type to defeat Flow's typechecking. Here are examples of upcasting (which is allowed), downcasting (which is forbidden), and using <code>any</code>.</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">class Base {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">class Child extends Base {}</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var child: Child = new Child();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Upcast from Child to Base, a more general type: OK</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">var base: Base = new Child();</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Upcast from Child to Base, a more general type: OK</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(child: Base);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Downcast from Base to Child: unsafe, ERROR</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(base: Child);</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Upcast base to any then downcast any to Child.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">// Unsafe downcasting from any is allowed: OK</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">((base: any): Child);</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="more-examples">More examples<a href="#more-examples" class="hash-link" aria-label="Direct link to More examples" title="Direct link to More examples">​</a></h2><p>Typecasts are particularly useful to check assumptions and help Flow infer the types you intend. Here are some examples:</p><div class="language-JavaScript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-JavaScript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain">(x: number) // Make Flow check that x is a number</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(0: ?number) // Tells Flow that this expression is actually nullable.</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">(null: ?number) // Tells Flow that this expression is a nullable number.</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="transformations">Transformations<a href="#transformations" class="hash-link" aria-label="Direct link to Transformations" title="Direct link to Transformations">​</a></h2><p>Like type annotations and other Flow features, typecasts need to be transformed away before the code can be run. The transforms will be available in react-tools <code>0.13.0</code> when it is published soon, but for now they're available in <code>0.13.0-beta.2</code>, which you can install with</p><div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> react-tools@0.13.0-beta.2</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div>]]></content>
        <author>
            <name>Basil Hosmer</name>
        </author>
    </entry>
</feed>