Flow contains a linting framework that can tell you about more than just type errors. This framework is highly configurable in order to show you the information you want and hide the information you don’t.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
const x: ?number = 0;
if (x) {}
import type {Foo} from './untyped.js';
if (x) {}
if (x) {}
if (x) {}
if (x) {}
import type {Bar} from './untyped.js';
|
{"value":" /* flowlint\n * sketchy-null:error,\n * untyped-type-import:error\n */\nconst x: ?number = 0;\n\nif (x) {} // Error\nimport type {Foo} from './untyped.js'; // Error\n\n// flowlint-next-line sketchy-null:off\nif (x) {} // No Error\n\nif (x) {} /* flowlint-line sketchy-null:off */ // No Error\n\n// flowlint sketchy-null:off\nif (x) {} // No Error\nif (x) {} // No Error\nimport type {Bar} from './untyped.js'; // Error; unlike a $FlowFixMe, a flowlint comment only suppresses one particular type of error.\n// flowlint sketchy-null:error\n","tokens":[{"type":"Block","context":"comment","value":"/* flowlint\n * sketchy-null:error,\n * untyped-type-import:error\n */","line":1,"start":1,"end":75},{"type":"T_CONST","context":"normal","value":"const","line":5,"start":76,"end":81},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":5,"start":82,"end":83},{"type":"T_COLON","context":"type","value":":","line":5,"start":83,"end":84},{"type":"T_PLING","context":"type","value":"?","line":5,"start":85,"end":86},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":5,"start":86,"end":92},{"type":"T_ASSIGN","context":"normal","value":"=","line":5,"start":93,"end":94},{"type":"T_NUMBER","context":"normal","value":"0","line":5,"start":95,"end":96},{"type":"T_SEMICOLON","context":"normal","value":";","line":5,"start":96,"end":97},{"type":"T_IF","context":"normal","value":"if","line":7,"start":99,"end":101},{"type":"T_LPAREN","context":"normal","value":"(","line":7,"start":102,"end":103},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":7,"start":103,"end":104},{"type":"T_RPAREN","context":"normal","value":")","line":7,"start":104,"end":105},{"type":"T_LCURLY","context":"normal","value":"{","line":7,"start":106,"end":107},{"type":"T_RCURLY","context":"normal","value":"}","line":7,"start":107,"end":108},{"type":"Line","context":"comment","value":"// Error","line":7,"start":109,"end":117},{"type":"T_IMPORT","context":"normal","value":"import","line":8,"start":118,"end":124},{"type":"T_TYPE","context":"normal","value":"type","line":8,"start":125,"end":129},{"type":"T_LCURLY","context":"normal","value":"{","line":8,"start":130,"end":131},{"type":"T_IDENTIFIER","context":"type","value":"Foo","line":8,"start":131,"end":134},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":134,"end":135},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":8,"start":136,"end":140},{"type":"T_STRING","context":"normal","value":"'./untyped.js'","line":8,"start":141,"end":155},{"type":"T_SEMICOLON","context":"normal","value":";","line":8,"start":155,"end":156},{"type":"Line","context":"comment","value":"// Error","line":8,"start":157,"end":165},{"type":"Line","context":"comment","value":"// flowlint-next-line sketchy-null:off","line":10,"start":167,"end":205},{"type":"T_IF","context":"normal","value":"if","line":11,"start":206,"end":208},{"type":"T_LPAREN","context":"normal","value":"(","line":11,"start":209,"end":210},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":11,"start":210,"end":211},{"type":"T_RPAREN","context":"normal","value":")","line":11,"start":211,"end":212},{"type":"T_LCURLY","context":"normal","value":"{","line":11,"start":213,"end":214},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":214,"end":215},{"type":"Line","context":"comment","value":"// No Error","line":11,"start":216,"end":227},{"type":"T_IF","context":"normal","value":"if","line":13,"start":229,"end":231},{"type":"T_LPAREN","context":"normal","value":"(","line":13,"start":232,"end":233},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":13,"start":233,"end":234},{"type":"T_RPAREN","context":"normal","value":")","line":13,"start":234,"end":235},{"type":"T_LCURLY","context":"normal","value":"{","line":13,"start":236,"end":237},{"type":"T_RCURLY","context":"normal","value":"}","line":13,"start":237,"end":238},{"type":"Block","context":"comment","value":"/* flowlint-line sketchy-null:off */","line":13,"start":239,"end":275},{"type":"Line","context":"comment","value":"// No Error","line":13,"start":276,"end":287},{"type":"Line","context":"comment","value":"// flowlint sketchy-null:off","line":15,"start":289,"end":317},{"type":"T_IF","context":"normal","value":"if","line":16,"start":318,"end":320},{"type":"T_LPAREN","context":"normal","value":"(","line":16,"start":321,"end":322},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":16,"start":322,"end":323},{"type":"T_RPAREN","context":"normal","value":")","line":16,"start":323,"end":324},{"type":"T_LCURLY","context":"normal","value":"{","line":16,"start":325,"end":326},{"type":"T_RCURLY","context":"normal","value":"}","line":16,"start":326,"end":327},{"type":"Line","context":"comment","value":"// No Error","line":16,"start":328,"end":339},{"type":"T_IF","context":"normal","value":"if","line":17,"start":340,"end":342},{"type":"T_LPAREN","context":"normal","value":"(","line":17,"start":343,"end":344},{"type":"T_IDENTIFIER","context":"normal","value":"x","line":17,"start":344,"end":345},{"type":"T_RPAREN","context":"normal","value":")","line":17,"start":345,"end":346},{"type":"T_LCURLY","context":"normal","value":"{","line":17,"start":347,"end":348},{"type":"T_RCURLY","context":"normal","value":"}","line":17,"start":348,"end":349},{"type":"Line","context":"comment","value":"// No Error","line":17,"start":350,"end":361},{"type":"T_IMPORT","context":"normal","value":"import","line":18,"start":362,"end":368},{"type":"T_TYPE","context":"normal","value":"type","line":18,"start":369,"end":373},{"type":"T_LCURLY","context":"normal","value":"{","line":18,"start":374,"end":375},{"type":"T_IDENTIFIER","context":"type","value":"Bar","line":18,"start":375,"end":378},{"type":"T_RCURLY","context":"normal","value":"}","line":18,"start":378,"end":379},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":18,"start":380,"end":384},{"type":"T_STRING","context":"normal","value":"'./untyped.js'","line":18,"start":385,"end":399},{"type":"T_SEMICOLON","context":"normal","value":";","line":18,"start":399,"end":400},{"type":"Line","context":"comment","value":"// Error; unlike a $FlowFixMe, a flowlint comment only suppresses one particular type of error.","line":18,"start":401,"end":496},{"type":"Line","context":"comment","value":"// flowlint sketchy-null:error","line":19,"start":497,"end":527}],"errors":[]}
Within the -lints flag and the flowconfig, rules lower down override rules higher up, allowing you to write things like
The lint settings parser is fairly intelligent and will stop you if you write a redundant rule, a rule that gets completely overwritten, or an unused suppression. This should prevent most accidental misconfigurations of lint rules.