---
title: "Version 0.21.0"
short-title: "Version 0.21.0"
authors: [gabe-levi]
hide_table_of_contents: true
---

:::info[Historical]
This post announced Flow v0.21.0. For current features and behavior, see the [Flow documentation](/en/docs/).
:::

Yesterday we deployed Flow v0.21.0! As always, we've listed out the most
interesting changes in the
[Changelog](https://github.com/facebook/flow/blob/master/Changelog.md#v0210).
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!

### JSX Intrinsics

If you're writing JSX, it's probably a mix of your own React Components and
some intrinsics. For example, you might write

```js
render() {
  return <div><FluffyBunny name="Fifi" /></div>;
}
```

In this example, `FluffyBunny` is a React Component you wrote and `div` 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 `any`. 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!

<!--truncate-->

#### Example of how to use JSX intrinsics

.flowconfig

```js
[libs]
myLib.js
```

myLib.js

```js
// JSXHelper is a type alias to make this example more concise.
// There's nothing special or magic here.
// JSXHelper<{name: string}> is a React component
// with the single string property "name", which has a default
type JSXHelper<T> = Class<ReactComponent<T,T,mixed>>;

// $JSXIntrinsics is special and magic.
// This declares the types for `div` and `span`
type $JSXIntrinsics = {
  div: JSXHelper<{id: string}>,
  span: JSXHelper<{id: string, class: string}>,
};
```

myCode.js

```js
<div id="asdf" />; // No error
<div id={42} />; // Error: `id` prop is a string, not a number!
```

#### What is going on here?

The new bit of magic is this `$JSXIntrinsics` type alias. When Flow sees
`<foo />` it will look to see if `$JSXIntrinsics` exists and if so will grab
the type of `$JSXIntrinsics['foo']`. It will use this type to figure out which
properties are available and need to be set.

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.

### Smarter string refinements

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:

```js
class Person {
  name: ?string;
  ...
  getName(): string {
    // Before the if, this.name could be null, undefined, or a string
    if (this.name != null) {
      // But now the programmer has refined this.name to definitely be a string
      return this.name;
    }
    // And now we know that this.name is null or undefined.
    return 'You know who';
  }
}
```

#### New string refinements

In v0.21.0, one of the refinements we added is the ability to refine types by
comparing them to strings.

This is useful for refining unions of string literals into string literals

```js
function test(x: 'foo' | 'bar'): 'foo' {
  if (x === 'foo') {
    // Now Flow understands that x has the type 'foo'
    return x;
  } else {
    return 'foo';
  }
}
```

And can also narrow the value of strings:

```js
function test(x: string): 'foo' {
  if (x === 'foo') {
    // Now Flow knows x has the type 'foo'
    return x;
  } else {
    return 'foo';
  }
}
```

This is one of the many refinements that Flow currently can recognize and
follow, and we'll keep adding more! Stay tuned!
