Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jamiebuilds
Last active June 4, 2017 04:58
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jamiebuilds/8d64f5ec1d5d3f436d4a0b8055278966 to your computer and use it in GitHub Desktop.
Save jamiebuilds/8d64f5ec1d5d3f436d4a0b8055278966 to your computer and use it in GitHub Desktop.
Flow Tricks
// @flow
function getOptions() {
return { num: 42, str: "val" };
// ^ Type of this return is inferred without type annotation.
}
/*::
// ^ Comments like this are part of Flow's Comment Syntax.
// They allow you to include any additional syntax and Flow will parse it
// like you haven't commented it out. Allowing you to write Flow code without
// breaking JavaScript at runtime.
// Despite the syntax highlighting this is still in a comment so it won't
// execute.
var __options__ = getOptions();
// ^ Flow will assign the inferred return type to the __options__
// value.
// What we've just done is interesting because we've extracted a type from
// an arbitrary expression. Normal type annotations cannot do this (hopefully
// in the future they will be able to).
// Now we can create a type alias with our extracted inferred type.
type Options = typeof __options__;
// ^ typeof extracts the type from the __options__ value.
*/
// Now we can use the Options type alias as a type annotation. Our code is type
// checked:
var options /*: Options */ = {
num: "hi", // error: string should be number
str: 42 // error: number should be string
};
// Note that all of the above is valid JavaScript syntax. We've just been using
// comments so this is what JavaScript sees:
function getOptions() {
return { num: 42, str: "val" };
}
var options = {
num: "hi",
str: 42
};
// Maybe types might seem appealing to use any time you might want to return
// `undefined` or `null`, but they are actually a bit of a trap.
//
// Let's imagine this function with the return type `?number`
function method(bool: boolean): ?number {
let val;
if (bool) {
val = 1;
}
return val; // Works!
}
// It works and it passes type checking, it won't cause our program to throw
// an error. But it will cause it to behave differently than we intended
// because we've forgotten to handle the `else` case.
//
// If we instead change the return type to `number | null` we'll get an error:
function method(bool: boolean): number | null {
let val;
if (bool) {
val = 1;
}
return val; // Error! Returned `undefined` instead of `number` or `null`
}
// Then we can update our method:
function method(bool: boolean): number | null {
let val;
if (bool) {
val = 1;
} else {
val = 2;
}
return val; // Works!
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment