eslint-plugin-flowtype-esm

Flowtype linting rules for ESLint.

Usage no npm install needed!

<script type="module">
  import eslintPluginFlowtypeEsm from 'https://cdn.skypack.dev/eslint-plugin-flowtype-esm';
</script>

README

eslint-plugin-flowtype

GitSpo Mentions NPM version Travis build status js-canonical-style

Flow type linting rules for ESLint.

Installation

  1. Install ESLint.
  2. Install babel-eslint parser (ESLint parser does not support type annotations).
  3. Install eslint-plugin-flowtype plugin.
npm install eslint --save-dev
npm install babel-eslint --save-dev
npm install eslint-plugin-flowtype --save-dev

# Or all at once:
npm install eslint babel-eslint eslint-plugin-flowtype --save-dev

Configuration

  1. Set parser property to babel-eslint.
  2. Add plugins section and specify eslint-plugin-flowtype as a plugin.
  3. Enable rules.
{
  "parser": "babel-eslint",
  "plugins": [
    "flowtype"
  ],
  "rules": {
    "flowtype/boolean-style": [
      2,
      "boolean"
    ],
    "flowtype/define-flow-type": 1,
    "flowtype/delimiter-dangle": [
      2,
      "never"
    ],
    "flowtype/generic-spacing": [
      2,
      "never"
    ],
    "flowtype/no-mixed": 2,
    "flowtype/no-primitive-constructor-types": 2,
    "flowtype/no-types-missing-file-annotation": 2,
    "flowtype/no-weak-types": 2,
    "flowtype/object-type-delimiter": [
      2,
      "comma"
    ],
    "flowtype/require-parameter-type": 2,
    "flowtype/require-readonly-react-props": 0,
    "flowtype/require-return-type": [
      2,
      "always",
      {
        "annotateUndefined": "never"
      }
    ],
    "flowtype/require-valid-file-annotation": 2,
    "flowtype/semi": [
      2,
      "always"
    ],
    "flowtype/space-after-type-colon": [
      2,
      "always"
    ],
    "flowtype/space-before-generic-bracket": [
      2,
      "never"
    ],
    "flowtype/space-before-type-colon": [
      2,
      "never"
    ],
    "flowtype/type-id-match": [
      2,
      "^([A-Z][a-z0-9]+)+Typequot;
    ],
    "flowtype/union-intersection-spacing": [
      2,
      "always"
    ],
    "flowtype/use-flow-type": 1,
    "flowtype/valid-syntax": 1
  },
  "settings": {
    "flowtype": {
      "onlyFilesWithFlowAnnotation": false
    }
  }
}

Shareable configurations

Recommended

This plugin exports a recommended configuration that enforces Flow type good practices.

To enable this configuration use the extends property in your .eslintrc config file:

{
  "extends": [
    "plugin:flowtype/recommended"
  ],
  "plugins": [
    "flowtype"
  ]
}

See ESLint documentation for more information about extending configuration files.

Community maintained configurations

The following are third-party submitted/ maintained configurations of eslint-plugin-flowtype:

Settings

onlyFilesWithFlowAnnotation

When true, only checks files with a @flow annotation in the first comment.

{
  "settings": {
    "flowtype": {
      "onlyFilesWithFlowAnnotation": true
    }
  }
}

Rules

array-style-complex-type

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces a particular annotation style of complex types.

Type is considered complex in these cases:

This rule takes one argument.

If it is 'verbose' then a problem is raised when using Type[] instead of Array<Type>.

If it is 'shorthand' then a problem is raised when using Array<Type> instead of Type[].

The default value is 'verbose'.

The following patterns are considered problems:

type X = (?string)[]
// Message: Use "Array<?string>", not "(?string)[]"

// Options: ["verbose"]
type X = (?string)[]
// Message: Use "Array<?string>", not "(?string)[]"

// Options: ["shorthand"]
type X = Array<?string>
// Message: Use "(?string)[]", not "Array<?string>"

// Options: ["shorthand"]
type X = Array<{foo: string}>
// Message: Use "{foo: string}[]", not "Array<{foo: string}>"

type X = (string | number)[]
// Message: Use "Array<string | number>", not "(string | number)[]"

type X = (string & number)[]
// Message: Use "Array<string & number>", not "(string & number)[]"

type X = [string, number][]
// Message: Use "Array<[string, number]>", not "[string, number][]"

type X = {foo: string}[]
// Message: Use "Array<{foo: string}>", not "{foo: string}[]"

type X = (string => number)[]
// Message: Use "Array<string => number>", not "(string => number)[]"

type X = {
    foo: string,
    bar: number
}[]
// Message: Use "Array<{ foo: string, bar: number }>", not "{ foo: string, bar: number }[]"

type X = {
    foo: string,
    bar: number,
    quo: boolean,
    hey: Date
}[]
// Message: Use "Array<Type>", not "Type[]"

The following patterns are not considered problems:

type X = Array<?string>

// Options: ["verbose"]
type X = Array<?string>

// Options: ["shorthand"]
type X = (?string)[]

// Options: ["shorthand"]
type X = Array<string>

// Options: ["shorthand"]
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type X = Array<?string>

array-style-simple-type

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces a particular array type annotation style of simple types.

Type is considered simple in these cases:

This rule takes one argument.

If it is 'verbose' then a problem is raised when using Type[] instead of Array<Type>.

If it is 'shorthand' then a problem is raised when using Array<Type> instead of Type[].

The default value is 'verbose'.

The following patterns are considered problems:

type X = string[]
// Message: Use "Array<string>", not "string[]"

// Options: ["verbose"]
type X = string[]
// Message: Use "Array<string>", not "string[]"

// Options: ["shorthand"]
type X = Array<string>
// Message: Use "string[]", not "Array<string>"

type X = Date[]
// Message: Use "Array<Date>", not "Date[]"

type X = Promise<string>[]
// Message: Use "Array<Promise<string>>", not "Promise<string>[]"

type X = $Keys<{foo: string}>[]
// Message: Use "Array<$Keys<{foo: string}>>", not "$Keys<{foo: string}>[]"

type X = any[]
// Message: Use "Array<any>", not "any[]"

type X = mixed[]
// Message: Use "Array<mixed>", not "mixed[]"

type X = void[]
// Message: Use "Array<void>", not "void[]"

type X = null[]
// Message: Use "Array<null>", not "null[]"

type X = string[][]
// Message: Use "Array<string[]>", not "string[][]"
// Message: Use "Array<string>", not "string[]"

type X = Promise<{
    foo: string,
    bar: number
}>[]
// Message: Use "Array<Promise<{ foo: string, bar: number }>>", not "Promise<{ foo: string, bar: number }>[]"

type X = Promise<{
    foo: string,
    bar: number,
    quo: boolean
}>[]
// Message: Use "Array<Type>", not "Type[]"

The following patterns are not considered problems:

type X = Array<string>

// Options: ["verbose"]
type X = Array<string>

// Options: ["shorthand"]
type X = string[]

type X = Array<Array<string>>

// Options: ["verbose"]
type X = (?string)[]

// Options: ["verbose"]
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type X = string[]

type X = Array

type X = typeof Array

arrow-parens

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces the consistent use of parentheses in arrow functions.

This rule has a string option and an object one.

String options are:

  • "always" (default) requires parens around arguments in all cases.
  • "as-needed" enforces no braces where they can be omitted.

Object properties for variants of the "as-needed" option:

  • "requireForBlockBody": true modifies the as-needed rule in order to require parens if the function body is in an instructions block (surrounded by braces).

The following patterns are considered problems:

a => {}
// Message: undefined

a => a
// Message: undefined

a => {
}
// Message: undefined

a.then(foo => {});
// Message: undefined

a.then(foo => a);
// Message: undefined

a(foo => { if (true) {}; });
// Message: undefined

a(async foo => { if (true) {}; });
// Message: undefined

// Options: ["as-needed"]
(a) => a
// Message: undefined

// Options: ["as-needed"]
(a,) => a
// Message: undefined

// Options: ["as-needed"]
async (a) => a
// Message: undefined

// Options: ["as-needed"]
async(a) => a
// Message: undefined

// Options: ["as-needed",{"requireForBlockBody":true}]
a => {}
// Message: undefined

// Options: ["as-needed",{"requireForBlockBody":true}]
(a) => a
// Message: undefined

// Options: ["as-needed",{"requireForBlockBody":true}]
async a => {}
// Message: undefined

// Options: ["as-needed",{"requireForBlockBody":true}]
async (a) => a
// Message: undefined

// Options: ["as-needed",{"requireForBlockBody":true}]
async(a) => a
// Message: undefined

The following patterns are not considered problems:

() => {}

(a) => {}

(a) => a

(a) => {
}

a.then((foo) => {});

a.then((foo) => { if (true) {}; });

a.then(async (foo) => { if (true) {}; });

// Options: ["always"]
() => {}

// Options: ["always"]
(a) => {}

// Options: ["always"]
(a) => a

// Options: ["always"]
(a) => {
}

// Options: ["always"]
a.then((foo) => {});

// Options: ["always"]
a.then((foo) => { if (true) {}; });

// Options: ["always"]
a.then(async (foo) => { if (true) {}; });

// Options: ["as-needed"]
() => {}

// Options: ["as-needed"]
a => {}

// Options: ["as-needed"]
a => a

// Options: ["as-needed"]
([a, b]) => {}

// Options: ["as-needed"]
({ a, b }) => {}

// Options: ["as-needed"]
(a = 10) => {}

// Options: ["as-needed"]
(...a) => a[0]

// Options: ["as-needed"]
(a, b) => {}

// Options: ["as-needed"]
async ([a, b]) => {}

// Options: ["as-needed"]
async (a, b) => {}

// Options: ["as-needed"]
(a: T) => a

// Options: ["as-needed"]
(a): T => a

// Options: ["as-needed",{"requireForBlockBody":true}]
() => {}

// Options: ["as-needed",{"requireForBlockBody":true}]
a => a

// Options: ["as-needed",{"requireForBlockBody":true}]
([a, b]) => {}

// Options: ["as-needed",{"requireForBlockBody":true}]
([a, b]) => a

// Options: ["as-needed",{"requireForBlockBody":true}]
({ a, b }) => {}

// Options: ["as-needed",{"requireForBlockBody":true}]
({ a, b }) => a + b

// Options: ["as-needed",{"requireForBlockBody":true}]
(a = 10) => {}

// Options: ["as-needed",{"requireForBlockBody":true}]
(...a) => a[0]

// Options: ["as-needed",{"requireForBlockBody":true}]
(a, b) => {}

// Options: ["as-needed",{"requireForBlockBody":true}]
a => ({})

// Options: ["as-needed",{"requireForBlockBody":true}]
async a => ({})

// Options: ["as-needed",{"requireForBlockBody":true}]
async a => a

// Options: ["as-needed",{"requireForBlockBody":true}]
(a: T) => a

// Options: ["as-needed",{"requireForBlockBody":true}]
(a): T => a

// Options: ["always",{"requireForBlockBody":true}]
<T>(a: T) => a

// Options: ["as-needed",{"requireForBlockBody":false}]
<T>(a: T) => { return a; }

// Options: ["always",{"requireForBlockBody":true}]
<T>(a: T) => { return a; }

// Options: ["as-needed",{"requireForBlockBody":true}]
<T>(a: T) => { return a; }

// Options: ["as-needed",{"requireForBlockBody":true}]
(a): %checks => typeof a === "number"

boolean-style

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces a particular style for boolean type annotations. This rule takes one argument.

If it is 'boolean' then a problem is raised when using bool instead of boolean.

If it is 'bool' then a problem is raised when using boolean instead of bool.

The default value is 'boolean'.

The following patterns are considered problems:

type X = bool
// Message: Use "boolean", not "bool"

// Options: ["boolean"]
type X = bool
// Message: Use "boolean", not "bool"

// Options: ["bool"]
type X = boolean
// Message: Use "bool", not "boolean"

The following patterns are not considered problems:

type X = boolean

// Options: ["boolean"]
type X = boolean

// Options: ["bool"]
type X = bool

// Options: ["boolean"]
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type X = bool

define-flow-type

Marks Flow type identifiers as defined.

Used to suppress no-undef reporting of type identifiers.

The following patterns are not considered problems:

var a: AType
// Additional rules: {"no-undef":2}

var a: AType; var b: AType
// Additional rules: {"no-undef":2}

var a; (a: AType)
// Additional rules: {"no-undef":2}

var a: AType<BType>
// Additional rules: {"no-undef":2}

type A = AType
// Additional rules: {"no-undef":2}

declare type A = number
// Additional rules: {"no-undef":2}

opaque type A = AType
// Additional rules: {"no-undef":2}

function f(a: AType) {}
// Additional rules: {"no-undef":2}

function f(a: AType.a) {}
// Additional rules: {"no-undef":2}

function f(a: AType.a.b) {}
// Additional rules: {"no-undef":2}

function f(a): AType {}; var a: AType
// Additional rules: {"no-undef":2}

function f(a): AType {}
// Additional rules: {"no-undef":2}

class C { a: AType }
// Additional rules: {"no-undef":2}

class C { a: AType.a }
// Additional rules: {"no-undef":2}

class C { a: AType.a.b }
// Additional rules: {"no-undef":2}

class C implements AType {}
// Additional rules: {"no-undef":2}

declare interface A {}
// Additional rules: {"no-undef":2}

({ a: ({b() {}}: AType) })
// Additional rules: {"no-undef":2}

type X = {Y<AType>(): BType}
// Additional rules: {"no-undef":2}

// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}

/**
* Copyright 2019 no corp
* @flow
*/
type Foo = $ReadOnly<{}>
// Additional rules: {"no-undef":2}

var a: AType
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

var a: AType; var b: AType
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

var a; (a: AType)
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

var a: AType<BType>
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

type A = AType
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

declare type A = number
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

opaque type A = AType
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

function f(a: AType) {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

function f(a: AType.a) {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

function f(a: AType.a.b) {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

function f(a): AType {}; var a: AType
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

function f(a): AType {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

class C { a: AType }
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

class C { a: AType.a }
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

class C { a: AType.a.b }
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

class C implements AType {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

declare interface A {}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

({ a: ({b() {}}: AType) })
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

type X = {Y<AType>(): BType}
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}

/**
* Copyright 2019 no corp
* @flow
*/
type Foo = $ReadOnly<{}>
// Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]}

delimiter-dangle

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces consistent use of trailing commas in Object and Tuple annotations.

This rule takes three arguments where the possible values are the same as ESLint's default comma-dangle rule:

  1. The first argument is for Object and Tuple annotations. The default value is 'never'.
  2. The second argument is used for Interface annotations. This defaults to the value of the first argument.
  3. The third argument is used for inexact object notation (trailing ...). The default value is 'never'.

If it is 'never' then a problem is raised when there is a trailing comma.

If it is 'always' then a problem is raised when there is no trailing comma.

If it is 'always-multiline' then a problem is raised when there is no trailing comma on a multi-line definition, or there is a trailing comma on a single-line definition.

If it is 'only-multiline' then a problem is raised when there is a trailing comma on a single-line definition. It allows, but does not enforce, trailing commas on multi-line definitions.

The following patterns are considered problems:

type X = { foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = { foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = { foo: string; }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = {
foo: string,
}
// Message: Unexpected trailing delimiter

// Options: ["always"]
type X = { foo: string }
// Message: Missing trailing delimiter

// Options: ["always"]
type X = {
foo: string
}
// Message: Missing trailing delimiter

// Options: ["always-multiline"]
type X = { foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["always-multiline"]
type X = {
foo: string
}
// Message: Missing trailing delimiter

// Options: ["only-multiline"]
type X = { foo: string; }
// Message: Unexpected trailing delimiter

// Options: ["always","never"]
interface X { foo: string; }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = { [key: string]: number, }
// Message: Unexpected trailing delimiter

// Options: ["always"]
type X = { [key: string]: number }
// Message: Missing trailing delimiter

// Options: ["always-multiline"]
type X = { [key: string]: number, }
// Message: Unexpected trailing delimiter

// Options: ["always-multiline"]
type X = {
[key: string]: number
}
// Message: Missing trailing delimiter

// Options: ["only-multiline"]
type X = { [key: string]: number; }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = { [key: string]: number, foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = {
[key: string]: number,
foo: string,
}
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = {
[key: string]: number,
aReallyLongPropertyNameHere: string,
}
// Message: Unexpected trailing delimiter

// Options: ["always"]
type X = { [key: string]: number, foo: string }
// Message: Missing trailing delimiter

// Options: ["always"]
type X = {
[key: string]: number;
foo: string
}
// Message: Missing trailing delimiter

// Options: ["always-multiline"]
type X = { [key: string]: number, foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["always-multiline"]
type X = {
[key: string]: number,
foo: string
}
// Message: Missing trailing delimiter

// Options: ["only-multiline"]
type X = { [key: string]: number, foo: string, }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = { foo: string, [key: string]: number, }
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = {
foo: string,
[key: string]: number,
}
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = {
aReallyLongPropertyNameHere: string,
[key: string]: number,
}
// Message: Unexpected trailing delimiter

// Options: ["always"]
type X = { foo: string, [key: string]: number }
// Message: Missing trailing delimiter

// Options: ["always"]
type X = { foo: string; [key: string]: number }
// Message: Missing trailing delimiter

// Options: ["always-multiline"]
type X = { foo: string, [key: string]: number; }
// Message: Unexpected trailing delimiter

// Options: ["always-multiline"]
type X = {
foo: string,
[key: string]: number
}
// Message: Missing trailing delimiter

// Options: ["only-multiline"]
type X = { foo: string, [key: string]: number; }
// Message: Unexpected trailing delimiter

type X = { ..., }
// Message: Unexpected trailing delimiter

type X = { ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = { ... }
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { ...; }
// Message: Unexpected trailing delimiter

type X = {
...,
}
// Message: Unexpected trailing delimiter

type X = {
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
...,
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = {
...
}
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = {
...
}
// Message: Missing trailing delimiter

type X = { foo: string, ..., }
// Message: Unexpected trailing delimiter

type X = { foo: string; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { foo: string, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { foo: string; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = { foo: string, ... }
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { foo: string, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { foo: string; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { foo: string, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { foo: string; ...; }
// Message: Unexpected trailing delimiter

type X = {
foo: string,
...,
}
// Message: Unexpected trailing delimiter

type X = {
foo: string;
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
foo: string,
...,
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
foo: string;
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = {
foo: string,
...
}
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = {
foo: string,
...
}
// Message: Missing trailing delimiter

type X = { [key: string]: number, ..., }
// Message: Unexpected trailing delimiter

type X = { [key: string]: number; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { [key: string]: number, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = { [key: string]: number; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = { [key: string]: number, ... }
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { [key: string]: number, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","always-multiline"]
type X = { [key: string]: number; ...; }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { [key: string]: number, ..., }
// Message: Unexpected trailing delimiter

// Options: ["never","never","only-multiline"]
type X = { [key: string]: number; ...; }
// Message: Unexpected trailing delimiter

type X = {
[key: string]: number,
...,
}
// Message: Unexpected trailing delimiter

type X = {
[key: string]: number;
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
[key: string]: number,
...,
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","never"]
type X = {
[key: string]: number;
...;
}
// Message: Unexpected trailing delimiter

// Options: ["never","never","always"]
type X = {
[key: string]: number,
...
}
// Message: Missing trailing delimiter

// Options: ["never","never","always-multiline"]
type X = {
[key: string]: number,
...
}
// Message: Missing trailing delimiter

type X = [string, number,]
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = [string, number,]
// Message: Unexpected trailing delimiter

// Options: ["never"]
type X = [
string,
number,
]
// Message: Unexpected trailing delimiter

// Options: ["always"]
type X = [string, number]
// Message: Missing trailing delimiter

// Options: ["always"]
type X = [
string,
number
]
// Message: Missing trailing delimiter

// Options: ["always-multiline"]
type X = [string, number,]
// Message: Unexpected trailing delimiter

// Options: ["always-multiline"]
type X = [
foo, string
]
// Message: Missing trailing delimiter

// Options: ["only-multiline"]
type X = [ number, string, ]
// Message: Unexpected trailing delimiter

The following patterns are not considered problems:

type X = { foo: string }

// Options: ["never"]
type X = { foo: string }

// Options: ["always"]
type X = { foo: string, }

// Options: ["always"]
type X = { foo: string; }

// Options: ["never"]
type X = {
foo: string
}

// Options: ["always"]
type X = {
foo: string,
}

// Options: ["always-multiline"]
type X = { foo: string }

// Options: ["always-multiline"]
type X = {
foo: string,
}

// Options: ["always-multiline"]
type X = {
foo: string;
}

// Options: ["only-multiline"]
type X = { foo: string }

// Options: ["only-multiline"]
type X = {
foo: string
}

// Options: ["only-multiline"]
type X = {
foo: string,
}

// Options: ["only-multiline"]
type X = {
foo: string;
}

// Options: ["never","always"]
interface X { foo: string; }

// Options: ["never"]
type X = {}

// Options: ["always"]
type X = {}

// Options: ["always-multiline"]
type X = {}

// Options: ["only-multiline"]
type X = {}

// Options: ["never"]
type X = { [key: string]: number }

// Options: ["always"]
type X = { [key: string]: number, }

// Options: ["always"]
type X = { [key: string]: number; }

// Options: ["always-multiline"]
type X = { [key: string]: number }

// Options: ["always-multiline"]
type X = {
[key: string]: number,
}

// Options: ["only-multiline"]
type X = {
[key: string]: number,
}

// Options: ["only-multiline"]
type X = {
[key: string]: number
}

// Options: ["only-multiline"]
type X = { [key: string]: number }

// Options: ["never"]
type X = { [key: string]: number, foo: string }

// Options: ["always"]
type X = { [key: string]: number, foo: string, }

// Options: ["always"]
type X = { [key: string]: number; foo: string; }

// Options: ["always-multiline"]
type X = { [key: string]: number, foo: string }

// Options: ["always-multiline"]
type X = {
[key: string]: number,
foo: string,
}

// Options: ["only-multiline"]
type X = {
[key: string]: number,
foo: string,
}

// Options: ["only-multiline"]
type X = {
[key: string]: number;
foo: string
}

// Options: ["only-multiline"]
type X = { [key: string]: number, foo: string }

// Options: ["never"]
type X = { foo: string, [key: string]: number }

// Options: ["always"]
type X = { foo: string, [key: string]: number, }

// Options: ["always"]
type X = { foo: string; [key: string]: number; }

// Options: ["always-multiline"]
type X = { foo: string, [key: string]: number }

// Options: ["always-multiline"]
type X = {
foo: string,
[key: string]: number,
}

// Options: ["only-multiline"]
type X = {
foo: string,
[key: string]: number,
}

// Options: ["only-multiline"]
type X = {
foo: string;
[key: string]: number
}

// Options: ["only-multiline"]
type X = { foo: string, [key: string]: number }

type X = { ... }

// Options: ["never","never","never"]
type X = { ... }

// Options: ["never","never","always"]
type X = { ..., }

// Options: ["never","never","always-multiline"]
type X = { ... }

// Options: ["never","never","only-multiline"]
type X = { ... }

type X = {
...
}

// Options: ["never","never","never"]
type X = {
...
}

// Options: ["never","never","always"]
type X = {
...,
 }

// Options: ["never","never","always"]
type X = {
...;
 }

// Options: ["never","never","always-multiline"]
type X = {
...,
}

// Options: ["never","never","always-multiline"]
type X = {
...;
}

// Options: ["never","never","only-multiline"]
type X = {
...
}

// Options: ["never","never","only-multiline"]
type X = {
...,
}

// Options: ["never","never","only-multiline"]
type X = {
...;
}

type X = { foo: string, ... }

// Options: ["never","never","never"]
type X = { foo: string, ... }

// Options: ["never","never","always"]
type X = { foo: string, ..., }

// Options: ["never","never","always"]
type X = { foo: string; ...; }

// Options: ["never","never","always-multiline"]
type X = { foo: string, ... }

// Options: ["never","never","only-multiline"]
type X = { foo: string, ... }

type X = {
foo: string,
...
}

// Options: ["never","never","never"]
type X = {
foo: string,
...
}

// Options: ["never","never","always"]
type X = {
foo: string,
...,
}

// Options: ["never","never","always"]
type X = {
foo: string;
...;
}

// Options: ["never","never","always-multiline"]
type X = {
foo: string,
...,
}

// Options: ["never","never","always-multiline"]
type X = {
foo: string;
...;
}

// Options: ["never","never","only-multiline"]
type X = {
foo: string,
...
}

// Options: ["never","never","only-multiline"]
type X = {
foo: string,
...,
}

// Options: ["never","never","only-multiline"]
type X = {
foo: string,
...;
}

// Options: ["never","never","never"]
type X = { [key: string]: number, ... }

// Options: ["never","never","always"]
type X = { [key: string]: number, ..., }

// Options: ["never","never","always"]
type X = { [key: string]: number; ...; }

// Options: ["never","never","always-multiline"]
type X = { [key: string]: number, ... }

// Options: ["never","never","only-multiline"]
type X = { [key: string]: number, ... }

// Options: ["never","never","never"]
type X = {
[key: string]: number,
...
}

// Options: ["never","never","always"]
type X = {
[key: string]: number,
...,
}

// Options: ["never","never","always"]
type X = {
[key: string]: number;
...;
}

// Options: ["never","never","always-multiline"]
type X = {
[key: string]: number,
...,
}

// Options: ["never","never","always-multiline"]
type X = {
[key: string]: number;
...;
}

// Options: ["never","never","only-multiline"]
type X = {
[key: string]: number,
...
}

// Options: ["never","never","only-multiline"]
type X = {
[key: string]: number,
...,
}

// Options: ["never","never","only-multiline"]
type X = {
[key: string]: number;
...;
}

type X = [string, number]

// Options: ["never"]
type X = [string, number]

// Options: ["never"]
type X = [
string,
number
]

// Options: ["always"]
type X = [string, number,]

// Options: ["always"]
type X = [
string,
number,
]

// Options: ["always-multiline"]
type X = [ foo, string ]

// Options: ["always-multiline"]
type X = [
foo, string,
]

// Options: ["only-multiline"]
type X = [ number, string ]

// Options: ["only-multiline"]
type X = [
number,
string
]

// Options: ["only-multiline"]
type X = [
number,
string,
]

// Options: ["never"]
type X = []

// Options: ["always"]
type X = []

// Options: ["always-multiline"]
type X = []

// Options: ["only-multiline"]
type X = []

generic-spacing

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces consistent spacing within generic type annotation parameters.

This rule takes one argument. If it is 'never' then a problem is raised when there is a space surrounding the generic type parameters. If it is 'always' then a problem is raised when there is no space surrounding the generic type parameters.

The default value is 'never'.

The following patterns are considered problems:

type X = Promise< string>
// Message: There must be no space at start of "Promise" generic type annotation

// Options: ["never"]
type X = Promise<  string>
// Message: There must be no space at start of "Promise" generic type annotation

type X = FooBar<string >
// Message: There must be no space at end of "FooBar" generic type annotation

type X = Promise< string >
// Message: There must be no space at start of "Promise" generic type annotation
// Message: There must be no space at end of "Promise" generic type annotation

type X = Promise< (foo), bar, (((baz))) >
// Message: There must be no space at start of "Promise" generic type annotation
// Message: There must be no space at end of "Promise" generic type annotation

// Options: ["always"]
type X = Promise<string >
// Message: There must be a space at start of "Promise" generic type annotation

// Options: ["always"]
type X = FooBar< string>
// Message: There must be a space at end of "FooBar" generic type annotation

// Options: ["always"]
type X = Promise<string>
// Message: There must be a space at start of "Promise" generic type annotation
// Message: There must be a space at end of "Promise" generic type annotation

// Options: ["always"]
type X = Promise<(foo), bar, (((baz)))>
// Message: There must be a space at start of "Promise" generic type annotation
// Message: There must be a space at end of "Promise" generic type annotation

// Options: ["always"]
type X = FooBar<  string >
// Message: There must be one space at start of "FooBar" generic type annotation

// Options: ["always"]
type X = FooBar< string  >
// Message: There must be one space at end of "FooBar" generic type annotation

// Options: ["always"]
type X = Promise<  (foo), bar, (((baz)))  >
// Message: There must be one space at start of "Promise" generic type annotation
// Message: There must be one space at end of "Promise" generic type annotation

The following patterns are not considered problems:

type X = Promise<string>

type X = Promise<(string)>

type X = Promise<(foo), bar, (((baz)))>

type X = Promise<
  (foo),
  bar,
  (((baz))),
>

// Options: ["always"]
type X = Promise< string >

// Options: ["always"]
type X = Promise< (string) >

// Options: ["always"]
type X = Promise< (foo), bar, (((baz))) >

newline-after-flow-annotation

This rule requires an empty line after the Flow annotation.

Options

The rule has a string option:

  • "always" (default): Enforces that @flow annotations be followed by an empty line, separated by newline (LF)
  • "always-windows": Identical to "always", but will use a CRLF when autofixing
  • "never": Enforces that @flow annotations are not followed by empty lines
{
  "rules": {
    "flowtype/newline-after-flow-annotation": [
      2,
      "always"
    ]
  }
}

The following patterns are considered problems:

// @flow
import Foo from './foo';
// Message: Expected newline after flow annotation

// Options: ["always"]
// @flow
import Foo from './foo';
// Message: Expected newline after flow annotation

// Options: ["always-windows"]
// @flow
import Foo from './foo';
// Message: Expected newline after flow annotation

// Options: ["never"]
// @flow


// Message: Expected no newline after flow annotation

The following patterns are not considered problems:

// Options: ["always"]
// @flow

import Foo from './foo';

// Options: ["always-windows"]
// @flow

import Foo from './foo';

// Options: ["never"]
// @flow
import Foo from './foo';

no-dupe-keys

Checks for duplicate properties in Object annotations.

This rule mirrors ESLint's no-dupe-keys rule.

{
    "rules": {
        "flowtype/no-dupe-keys": 2
    }
}

The following patterns are considered problems:

type f = { a: number, b: string, a: number }
// Message: Duplicate property.

type f = { a: number, b: string, a: string }
// Message: Duplicate property.

type f = { get(key: "a"): string, get(key: "a"): string }
// Message: Duplicate property.

type f = { get(key: 1): string, get(key: 1): string }
// Message: Duplicate property.

type f = { get(key: 1.1): string, get(key: 1.1): string }
// Message: Duplicate property.

type f = { get(key: true): string, get(key: true): string }
// Message: Duplicate property.

type f = { get(key: {a: 1}): string, get(key: {a: 1}):string }
// Message: Duplicate property.

var a = "a"; type f = { get(key: a): string, get(key: a): string }
// Message: Duplicate property.

var b = 1; type f = { get(key: b): string, get(key: b): string }
// Message: Duplicate property.

var c = true; type f = { get(key: c): string, get(key: c): string }
// Message: Duplicate property.

var d = {}; type f = { get(key: d): string, get(key: d): string }
// Message: Duplicate property.

var e = []; type f = { get(key: e): string, get(key: e): string }
// Message: Duplicate property.

var e = [1, "a"]; type f = { get(key: e): string, get(key: e): string }
// Message: Duplicate property.

function fn() {}; type f = { get(key: fn): string, get(key: fn): string }
// Message: Duplicate property.

The following patterns are not considered problems:

type FooType = { a: number, b: string, c: number }

// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type FooType = { a: number, b: string, a: number }

type f = { get(key: "a"): string, get(key: "b"): string }

type f = { get(key: 1): string, get(key: 2): string }

type f = { get(key: 1.1): string, get(key: 1.2): string }

type f = { get(key: true): string, get(key: false): string }

type f = { get(key: ["a", 1]): string, get(key: ["a", 2]): string }

type f = { get(key: ["a", ["b", 1]]): string, get(key: ["a", ["b", 2]]): string }

type f = { a: number, b: string, c: number }

type f = { get(key: "a"): string, get(key: "b"): string }

type f = { get(key: "a"): string, get(key: "a", key2: "b"): string }

type f = { get(key: "a"): string, get(key: 1): string }

type f = { get(key: { a: 1 }): string, get(key: { a: 2 }): string}

var a = {}; var b = {}; type f = { get(key: a): string, get(key: b): string }

var a = 1; var b = 1; type f = { get(key: a): string, get(key: b): string }

type a = { b: <C>(config: { ...C, key: string}) => C }

export interface Foo { get foo(): boolean; get bar(): string; }

no-existential-type

Disallows use of the existential type (*). See more

{
  "rules": {
    "flowtype/no-existential-type": 2
  }
}

The following patterns are considered problems:

type T = *;
// Message: Unexpected use of existential type (*).

type T = U<*, *>;
// Message: Unexpected use of existential type (*).
// Message: Unexpected use of existential type (*).

const f: (*) => null = () => null;
// Message: Unexpected use of existential type (*).

The following patterns are not considered problems:

type T = string | null

no-flow-fix-me-comments

Disallows $FlowFixMe comment suppressions.

This is especially useful as a warning to ensure instances of $FlowFixMe in your codebase get fixed over time.

Options

This rule takes an optional RegExp that comments a text RegExp that makes the supression valid.

{
    "rules": {
        "flowtype/no-flow-fix-me-comments": [
            1,
            "TODO\s+[0-9]+"
        ]
    }
}

The following patterns are considered problems:

// $FlowFixMe I am doing something evil here
const text = 'HELLO';
// Message: $FlowFixMe is treated as `any` and should be fixed.

// Options: ["TODO [0-9]+"]
// $FlowFixMe I am doing something evil here
const text = 'HELLO';
// Message: $FlowFixMe is treated as `any` and should be fixed. Fix it or match `/TODO [0-9]+/`.

// Options: ["TODO [0-9]+"]
// $FlowFixMe TODO abc 47 I am doing something evil here
const text = 'HELLO';
// Message: $FlowFixMe is treated as `any` and should be fixed. Fix it or match `/TODO [0-9]+/`.

// $FlowFixMeProps I am doing something evil here
const text = 'HELLO';
// Message: $FlowFixMe is treated as `any` and should be fixed.

// Options: ["TODO [0-9]+"]
// $FlowFixMeProps I am doing something evil here
const text = 'HELLO';
// Message: $FlowFixMe is treated as `any` and should be fixed. Fix it or match `/TODO [0-9]+/`.

The following patterns are not considered problems:

const text = 'HELLO';

// Options: ["TODO [0-9]+"]
// $FlowFixMe TODO 48
const text = 'HELLO';

no-mixed

Warns against "mixed" type annotations. These types are not strict enough and could often be made more specific.

The following patterns are considered problems:

The following patterns are considered problems:

function foo(thing): mixed {}
// Message: Unexpected use of mixed type

function foo(thing): Promise<mixed> {}
// Message: Unexpected use of mixed type

function foo(thing): Promise<Promise<mixed>> {}
// Message: Unexpected use of mixed type

The following patterns are not considered problems:

function foo(thing): string {}

function foo(thing): Promise<string> {}

function foo(thing): Promise<Promise<string>> {}

(foo?: string) => {}

(foo: ?string) => {}

(foo: { a: string }) => {}

(foo: { a: ?string }) => {}

(foo: string[]) => {}

type Foo = string

type Foo = { a: string }

type Foo = { (a: string): string }

function foo(thing: string) {}

var foo: string

class Foo { props: string }

no-mutable-array

The --fix option on the command line automatically fixes problems reported by this rule.

Requires use of $ReadOnlyArray instead of just Array or array shorthand notation. $ReadOnlyArray is immutable array collection type and the superclass of Array and tuple types in Flow. Use of $ReadOnlyArray instead of Array can solve some "problems" in typing with Flow (e.g., 1, 2).

General reasons for using immutable data structures:

  • They are simpler to construct, test, and use
  • They help to avoid temporal coupling
  • Their usage is side-effect free (no defensive copies)
  • Identity mutability problem is avoided
  • They always have failure atomicity
  • They are much easier to cache

Note that initialization of a variable with an empty array is considered valid (e.g., const values: Array<string> = [];). This behavior resembles the behavior of Flow's unsealed objects, as it is assumed that empty array is intended to be mutated.

The following patterns are considered problems:

type X = Array<string>
// Message: Use "$ReadOnlyArray" instead of "Array"

type X = string[]
// Message: Use "$ReadOnlyArray" instead of array shorthand notation

const values: Array<Array<string>> = [];
// Message: Use "$ReadOnlyArray" instead of "Array"

let values: Array<Array<string>>;
// Message: Use "$ReadOnlyArray" instead of "Array"
// Message: Use "$ReadOnlyArray" instead of "Array"

The following patterns are not considered problems:

type X = $ReadOnlyArray<string>

const values: Array<$ReadOnlyArray<string>> = [];

const values: $ReadOnlyArray<string>[] = [];

const values: Array<$ReadOnlyArray<string>> = new Array();

const values: Array<$ReadOnlyArray<string>> = Array();

no-primitive-constructor-types

Disallows use of primitive constructors as types, such as Boolean, Number and String. See more.

{
    "rules": {
        "flowtype/no-primitive-constructor-types": 2
    }
}

The following patterns are considered problems:

type x = Number
// Message: Unexpected use of Number constructor type.

type x = String
// Message: Unexpected use of String constructor type.

type x = Boolean
// Message: Unexpected use of Boolean constructor type.

type x = { a: Number }
// Message: Unexpected use of Number constructor type.

type x = { a: String }
// Message: Unexpected use of String constructor type.

type x = { a: Boolean }
// Message: Unexpected use of Boolean constructor type.

(x: Number) => {}
// Message: Unexpected use of Number constructor type.

(x: String) => {}
// Message: Unexpected use of String constructor type.

(x: Boolean) => {}
// Message: Unexpected use of Boolean constructor type.

The following patterns are not considered problems:

type x = number

type x = string

type x = boolean

type x = { a: number }

type x = { a: string }

type x = { a: boolean }

(x: number) => {}

(x: string) => {}

(x: boolean) => {}

type x = MyNumber

type x = MyString

type x = MyBoolean

no-types-missing-file-annotation

Disallows Flow type imports, aliases, and annotations in files missing a valid Flow file declaration (or a @noflow annotation).

{
    "rules": {
        "flowtype/no-types-missing-file-annotation": 2
    }
}

The following patterns are considered problems:

const x: number = 42;
// Message: Type annotations require valid Flow declaration.

type FooType = number;
// Message: Type aliases require valid Flow declaration.

import type A from "a"
// Message: Type imports require valid Flow declaration.

import type {A} from "a"
// Message: Type imports require valid Flow declaration.

import {type A} from "a"
// Message: Type imports require valid Flow declaration.

export type {A} from "a"
// Message: Type exports require valid Flow declaration.

function t<T>(): T{}
// Message: Type annotations require valid Flow declaration.

// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
const x: number = 42;
// Message: Type annotations require valid Flow declaration.

The following patterns are not considered problems:

// @flow
const x: number = 42;

/* @flow weak */
type FooType = number;

/* @noflow */
type FooType = number;

/* @noflow */
import type A from "a"

/* @noflow */
import {type A} from "a"

/* @noflow */
export type {A} from "a"

// an unrelated comment
// @flow
export type {A} from "a"

no-unused-expressions

An extension of ESLint's no-unused-expressions. This rule ignores type cast expressions, but otherwise behaves the same as ESLint's no-unused-expressions.

Bare type casts are useful, for example to assert the exhaustiveness of a switch:

type Action
  = { type: 'FOO', doFoo: (_: number) => void }
  | { type: 'BAR', doBar: (_: string) => void };

type State = { foo: number, bar: string };

function runFooBar(action: Action, state: State): void {
  switch (action.type) {
    case 'FOO':
      doFoo(state.foo);
      break;
    case 'BAR':
      doBar(state.bar);
      break;
    default:
      (action: empty);  // type error when `Action` is extended with new types
      console.error(`Impossible action: ${action.toString()}`);
  }
}

This rule takes the same arguments as ESLint's no-unused-expressions. See that rule's documentation for details.

The following patterns are considered problems:

foo + 1
// Message: Expected an assignment or function call and instead saw an expression.

The following patterns are not considered problems:

(foo: number)

no-weak-types

Warns against weak type annotations any, Object and Function. These types can cause flow to silently skip over portions of your code, which would have otherwise caused type errors.

This rule optionally takes one argument, an object to configure which type warnings to enable. By default, all of the warnings are enabled. e.g. to disable the any warning (allowing it to exist in your code), while continuing to warn about Object and Function:

{
    "rules": {
        "flowtype/no-weak-types": [2, {
            "any": false,
            "Object": true,
            "Function": true
        }]
    }
}

// or, the following is equivalent as default is true:

{
    "rules": {
        "flowtype/no-weak-types": [2, {
            "any": false
        }]
    }
}

The following patterns are considered problems:

function foo(thing): any {}
// Message: Unexpected use of weak type "any"

function foo(thing): Promise<any> {}
// Message: Unexpected use of weak type "any"

function foo(thing): Promise<Promise<any>> {}
// Message: Unexpected use of weak type "any"

function foo(thing): Object {}
// Message: Unexpected use of weak type "Object"

function foo(thing): Promise<Object> {}
// Message: Unexpected use of weak type "Object"

function foo(thing): Promise<Promise<Object>> {}
// Message: Unexpected use of weak type "Object"

function foo(thing): Function {}
// Message: Unexpected use of weak type "Function"

function foo(thing): Promise<Function> {}
// Message: Unexpected use of weak type "Function"

function foo(thing): Promise<Promise<Function>> {}
// Message: Unexpected use of weak type "Function"

(foo: any) => {}
// Message: Unexpected use of weak type "any"

(foo: Function) => {}
// Message: Unexpected use of weak type "Function"

(foo?: any) => {}
// Message: Unexpected use of weak type "any"

(foo?: Function) => {}
// Message: Unexpected use of weak type "Function"

(foo: { a: any }) => {}
// Message: Unexpected use of weak type "any"

(foo: { a: Object }) => {}
// Message: Unexpected use of weak type "Object"

(foo: any[]) => {}
// Message: Unexpected use of weak type "any"

type Foo = any
// Message: Unexpected use of weak type "any"

type Foo = Function
// Message: Unexpected use of weak type "Function"

type Foo = { a: any }
// Message: Unexpected use of weak type "any"

type Foo = { a: Object }
// Message: Unexpected use of weak type "Object"

type Foo = { (a: Object): string }
// Message: Unexpected use of weak type "Object"

type Foo = { (a: string): Function }
// Message: Unexpected use of weak type "Function"

function foo(thing: any) {}
// Message: Unexpected use of weak type "any"

function foo(thing: Object) {}
// Message: Unexpected use of weak type "Object"

var foo: Function
// Message: Unexpected use of weak type "Function"

var foo: Object
// Message: Unexpected use of weak type "Object"

class Foo { props: any }
// Message: Unexpected use of weak type "any"

class Foo { props: Object }
// Message: Unexpected use of weak type "Object"

var foo: any
// Message: Unexpected use of weak type "any"

// Options: [{"Function":false}]
type X = any; type Y = Function; type Z = Object
// Message: Unexpected use of weak type "any"
// Message: Unexpected use of weak type "Object"

// Options: [{"any":false,"Object":false}]
type X = any; type Y = Function; type Z = Object
// Message: Unexpected use of weak type "Function"

The following patterns are not considered problems:

function foo(thing): string {}

function foo(thing): Promise<string> {}

function foo(thing): Promise<Promise<string>> {}

(foo?: string) => {}

(foo: ?string) => {}

(foo: { a: string }) => {}

(foo: { a: ?string }) => {}

(foo: string[]) => {}

type Foo = string

type Foo = { a: string }

type Foo = { (a: string): string }

function foo(thing: string) {}

var foo: string

class Foo { props: string }

// Options: [{"any":false,"Object":false}]
type X = any; type Y = Object

// Options: [{"Function":false}]
type X = Function

// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
function foo(thing): Function {}

object-type-delimiter

The --fix option on the command line automatically fixes problems reported by this rule.

Enforces consistent separators between properties in Flow object types.

This rule takes one argument.

If it is 'comma' then a problem is raised when using ; as a separator.

If it is 'semicolon' then a problem is raised when using , as a separator.

The default value is 'comma'.

This rule is ported from babel/flow-object-type, however the default option was changed.

The following patterns are considered problems:

// Options: ["semicolon"]
type Foo = { a: Foo, b: Bar }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
type Foo = { a: Foo; b: Bar }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
type Foo = { [a: string]: Foo, [b: string]: Bar }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
type Foo = { [a: string]: Foo; [b: string]: Bar }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
type Foo = { (): Foo, (): Bar }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
type Foo = { (): Foo; (): Bar }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
declare class Foo { a: Foo, }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
declare class Foo { a: Foo; }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
declare class Foo { [a: string]: Foo, }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
declare class Foo { a: Foo; }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
declare class Foo { (): Foo, }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
declare class Foo { (): Foo; }
// Message: Prefer commas to semicolons in object and class types

// Options: ["semicolon"]
declare class Foo { static (): Foo, }
// Message: Prefer semicolons to commas in object and class types

// Options: ["comma"]
declare class Foo { static (): Foo; }
// Message: Prefer commas to semicolons in object and class types

The following patterns are not considered problems:

// Options: ["semicolon"]
type Foo = { a: Foo; b: Bar }

// Options: ["comma"]
type Foo = { a: Foo, b: Bar }

// Options: ["semicolon"]
type Foo = { [a: string]: Foo; [b: string]: Bar }

// Options: ["comma"]
type Foo = { [a: string]: Foo, [b: string]: Bar }

// Options: ["semicolon"]
type Foo = { (): Foo; (): Bar }

// Options: ["comma"]
type Foo = { (): Foo, (): Bar }

type Foo = { a: Foo, b: Bar }

type Foo = { [a: string]: Foo, [b: string]: Bar }

type Foo = { (): Foo, (): Bar }

// Options: ["semicolon"]
declare class Foo { a: Foo; }

// Options: ["comma"]
declare class Foo { a: Foo, }

// Options: ["semicolon"]
declare class Foo { [a: string]: Foo; }

// Options: ["comma"]
declare class Foo { [a: string]: Foo, }

// Options: ["semicolon"]
declare class Foo { (): Foo; }

// Options: ["comma"]
declare class Foo { (): Foo, }

// Options: ["semicolon"]
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type Foo = { a: Foo, b: Bar }

require-compound-type-alias

Requires to make a type alias for all union and intersection types. If these are used in "raw" forms it might be tempting to just copy&paste them around the code. However, this brings sort of a source code pollution and unnecessary changes on several parts when these compound types need to be changed.

Options

The rule has a string option:

  • "never"
  • "always"

The default value is "always".

The following patterns are considered problems:

function foo(bar: "A" | "B") {}
// Message: All union types must be declared with named type alias.

const foo: "A" | "B" = "A";
// Message: All union types must be declared with named type alias.

type Foo = { bar: "A" | "B" };
// Message: All union types must be declared with named type alias.

function foo(bar: { n: number } | { s: string }) {}
// Message: All union types must be declared with named type alias.

function foo(bar: { n: number } & { s: string }) {}
// Message: All intersection types must be declared with named type alias.

const foo: { n: number } & { s: string } = { n: 0, s: "" };
// Message: All intersection types must be declared with named type alias.

type Foo = { bar: { n: number } & { s: string } };
// Message: All intersection types must be declared with named type alias.

function foo(bar: { n: number } & { s: string }) {}
// Message: All intersection types must be declared with named type alias.

The following patterns are not considered problems:

type Foo = "A" | "B";

type Bar = "A" | "B"; function foo(bar: Bar) {}

type Foo = { disjoint: "A", n: number } | { disjoint: "B", s: string };

type Foo = { n: number } & { s: string };

type Bar = { n: number } & { s: string }; function foo(bar: Bar) {}

// Options: ["never"]
function foo(bar: "A" | "B") {}

// Options: ["never"]
function foo(bar: { n: number } & { s: string }) {}

require-exact-type

_The --fix option on the command