TypeError: “x" is not a function. Quale sviluppatore JavaScript non ha mai incontrato questo errore, magari su un sito in produzione? Non sarebbe invece fantastico intercettare questi errori durante lo sviluppo? In questo talk presenteremo Flow, uno static typechecker per javascript che ci può aiutare a scrivere codice più affidabile e sicuro. Il talk conterrà esempi concreti e demo. ATTENZIONE: può causare forti sbalzi di JavaScript fatigue!
8. What is Flowtype static typing?
function add(x: number, y: number) {
return x + y;
}
add(2, 3); // ok!
add(2, true); // boolean. This type is incompatible ...
14. Especially when
/**
* Adds a listener
* @param {string} event - The event
* @param {string} listener - The listener
* @return {object} An EventEmitter
*/
function addListener(event, listener); // types, nah..
19. Flowtype "vs" Typescript (cont'd)
Typescript is a language that compiles to JS.
It has language features that are not present in JS.
Examples: enums, visibility modifiers, short-hand constructors...
20. Flowtype "vs" Typescript (cont'd)
Flow is a typechecker.
It doesn't compile to anything, it just typechecks.
21. Flowtype + Babel ~= Typescript
(or at least you can compare them)
and actually
Flowtype + Babel + Webpack ~= Typescript
22. Flowtype "vs" Typescript (cont'd)
Type systems facts:
• Typescript is a lot more stable
• Typescript cares a lot less about soundness
• Typescript's type system is less powerful
24. Flowtype, get started
(cont'd)
Add the @flow pragma to all the files you want Flow to consider
/* @flow */
const answer = 42; // typechecks!
25. Easy on-boarding
Since you have to whitelist files, on-boarding is really easy.
You can tinker with JS, and then progressively make your code base
more solid.
You have an option, which is very unobstrutive and easy to bail from.
29. Type inference
// oh, I see, an array of strings
const names = [" foo", "bar ", "baz"];
// ah no, an array of strings and numbers
names.push(2);
// wait, you can't trim a number!
names.map(name => name.trim());
30. Native types
So, yes Flow knows about string, number and all the other native
types you would expect.
Also, it ships with typings for the JS standard library and some very
common API such as the DOM, Node.js and React.
31. Special types
• mixed is supertype of all types.
• any type can be used where a mixed is required.
• any is both supertype and subtype of all the types
• any type can be used where a any is required.
• it can fit where anything is required
34. Composite types
const user: { name: string, age: number } = {
// |-------- the type ---------|
name: 'Gabriele',
age: 27
};
35. Type aliases
type User = { name: string, age: number };
const user: User = { name: 'Gabriele', age: 27 };
function getFriendsOf(user: User): Array<User> {
...
}
39. Dealing with union types
function getUser(userId: string): Error | User { ... }
const result = getUser("foo");
if (result instanceof Error) {
console.log('AAAAAHHH!');
} else {
console.log(result.name);
}
41. Let's try!
function foo(x: number): number {
if (x > 42) {
return x;
}
}
NOPE!
We return number in some cases, but in others we can return
undefined.
42. Let's try again!
function foo(x: number): number | typeof undefined {
if (x > 42) {
return x;
}
}
(undefined is a value, typeof undefined is its type)
YEP! That's the return type.
43. Ok, that seems pretty common...
A | typeof undefined | null
has a syntax shorthand in Flow
Meet
?A
the nullable type
49. $FlowFixMe
type User = { name: string };
// $FlowFixMe
const u: User = { foo: 'hey' };
Disables typechecking on the next line
50. weak mode
// @flow weak
less aggressive type inference, useful when starting on a new project.
51. force the hand of the
typecheker
const x: number = 'foo'; // sorry, nope
const y: number = (('foo': any): number); // oh, ok
52. Third-party modules
You have some dependencies right?
npm install -g flow-typed
npm install --save-dev flow-bin
flow-typed install
It will install every compatible type definition it finds.
53. Stripping types
With Babel
npm install -D babel-plugin-transform-flow-strip-types
{ "plugins": ["transform-flow-strip-types"] }
With flow-remove-types
npm install -g flow-remove-types
flow-remove-types src/ --out-dir lib/
flow-node index.js # or run directly