flow-type-talk

A talk on using Flowtype for intermediate and advanced users

Stars
0
<title>reveal-md</title>
<link rel="stylesheet" href="./css/reveal.css" />
<link rel="stylesheet" href="./css/theme/simple.css" id="theme" />
<link rel="stylesheet" href="./css/highlight/zenburn.css" />
<link rel="stylesheet" href="./css/print/paper.css" type="text/css" media="print" />

By: Victor Powell

Specify the Flow version explicitly

[version]
0.104.0
[ignore]
<PROJECT_ROOT>/node_modules/.*
# Ignore all modules...
<PROJECT_ROOT>/node_modules/.*
# except these ones.
!<PROJECT_ROOT>/node_modules/baseui/.*
[ignore]
# ignore `dist` directory.
.*/dist/.*
$ flow ls
foo/bar/index.js
node_modules/wow/index.js
[lints]
untyped-type-import=error
untyped-import=error
flow-typed create-stub [email protected]
declare module 'flat' {
  declare module.exports: any;
}
- declare module 'flat/cli' {
-  declare module.exports: any;
- }

- declare module 'flat/test/test' {
-   declare module.exports: any;
- }
const x: ?number = 5;
if (x) {} // sketchy because x could be either null or 0.

If you're going to add any lint check, the most important of these is probably unclear-type. It will eror if you use an any.

The difference between spread and &

... is usually want you want.

type A = { prop: string };
type B = { prop: number };

({ prop: 'foo' }: A & B); // Error!
({ prop: 10 }: A & B); // Error!
({ prop: 'foo' }: {...A, ...B});
({ prop: 10 }: {...A, ...B});

[Try Flow]

You checked if thing was not undefined but Flow still complains

type Person = {| thing: string | void |};

const me: Person = { thing: 'Ive got value.' };

if (me.thing) {
  doAThing();
  print(me.thing); // Error!
}

function doAThing() {}
function print(message: string) {}
Cannot call `print` with `me.thing` bound to `message`
because undefined [1] is incompatible with string [2].

[Try Flow]

const foo = {};
foo.bar(); // No error!

[Try Flow]

// @flow

// Definitely has `foo`.
const b: {| foo: string |} = { foo: 'foo' };

function func1(a: {| foo: string | void |}) {
  // This signature says "I might set `a.foo`
  // to undefined."
}

func1(b); // Error!


// Definitely has `foo`.
const b: {| foo: string |} = { foo: 'foo' };

function func2(a: $ReadOnly<{| foo: string | void |}>) {
 // This signature says "I wont modify touch the
 // properties of `a`."
}

func2(b); // Works!

[Try Flow]

Flow does not enforce existance on array index access

const a: Array<{|foo: string|}> = [];
const b: string = a[0].foo; // `b` is actually undefined!

[Try Flow]

'Coverage' can be helpful but don't let it mislead you

That said, there was recently added experimental support for "trusted" coverage.

<script src="./js/reveal.js"></script>

<script>
  function extend() {
    var target = {};
    for (var i = 0; i < arguments.length; i++) {
      var source = arguments[i];
      for (var key in source) {
        if (source.hasOwnProperty(key)) {
          target[key] = source[key];
        }
      }
    }
    return target;
  }

  // Optional libraries used to extend on reveal.js
  var deps = [
    { src: './plugin/markdown/marked.js', condition: function() { return !!document.querySelector('[data-markdown]'); } },
    { src: './plugin/markdown/markdown.js', condition: function() { return !!document.querySelector('[data-markdown]'); } },
    { src: './plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
    { src: './plugin/zoom-js/zoom.js', async: true },
    { src: './plugin/notes/notes.js', async: true },
    { src: './plugin/math/math.js', async: true }
  ];

  // default options to init reveal.js
  var defaultOptions = {
    controls: true,
    progress: true,
    history: true,
    center: true,
    transition: 'default', // none/fade/slide/convex/concave/zoom
    dependencies: deps
  };

  // options from URL query string
  var queryOptions = Reveal.getQueryHash() || {};

  var options = extend(defaultOptions, {}, queryOptions);
</script>


<script>
  Reveal.initialize(options);
</script>