eslint-plugin-flowtype
Version:
Flowtype linting rules for ESLint.
2,131 lines (1,560 loc) • 177 kB
Markdown
<a name="eslint-plugin-flowtype"></a>
# eslint-plugin-flowtype
[](https://www.npmjs.org/package/eslint-plugin-flowtype)
[](https://travis-ci.com/github/gajus/eslint-plugin-flowtype)
[](https://github.com/gajus/canonical)
[Flow type](http://flowtype.org/) linting rules for ESLint.
* [eslint-plugin-flowtype](#eslint-plugin-flowtype)
* [Installation](#eslint-plugin-flowtype-installation)
* [Configuration](#eslint-plugin-flowtype-configuration)
* [Shareable configurations](#eslint-plugin-flowtype-configuration-shareable-configurations)
* [Community maintained configurations](#eslint-plugin-flowtype-configuration-community-maintained-configurations)
* [Settings](#eslint-plugin-flowtype-settings)
* [`onlyFilesWithFlowAnnotation`](#eslint-plugin-flowtype-settings-onlyfileswithflowannotation)
* [Rules](#eslint-plugin-flowtype-rules)
* [`array-style-complex-type`](#eslint-plugin-flowtype-rules-array-style-complex-type)
* [`array-style-simple-type`](#eslint-plugin-flowtype-rules-array-style-simple-type)
* [`arrow-parens`](#eslint-plugin-flowtype-rules-arrow-parens)
* [`boolean-style`](#eslint-plugin-flowtype-rules-boolean-style)
* [`define-flow-type`](#eslint-plugin-flowtype-rules-define-flow-type)
* [`delimiter-dangle`](#eslint-plugin-flowtype-rules-delimiter-dangle)
* [`enforce-line-break`](#eslint-plugin-flowtype-rules-enforce-line-break)
* [`generic-spacing`](#eslint-plugin-flowtype-rules-generic-spacing)
* [`interface-id-match`](#eslint-plugin-flowtype-rules-interface-id-match)
* [`newline-after-flow-annotation`](#eslint-plugin-flowtype-rules-newline-after-flow-annotation)
* [`no-dupe-keys`](#eslint-plugin-flowtype-rules-no-dupe-keys)
* [`no-duplicate-type-union-intersection-members`](#eslint-plugin-flowtype-rules-no-duplicate-type-union-intersection-members)
* [`no-existential-type`](#eslint-plugin-flowtype-rules-no-existential-type)
* [`no-flow-fix-me-comments`](#eslint-plugin-flowtype-rules-no-flow-fix-me-comments)
* [`no-internal-flow-type`](#eslint-plugin-flowtype-rules-no-internal-flow-type)
* [`no-mixed`](#eslint-plugin-flowtype-rules-no-mixed)
* [`no-mutable-array`](#eslint-plugin-flowtype-rules-no-mutable-array)
* [`no-primitive-constructor-types`](#eslint-plugin-flowtype-rules-no-primitive-constructor-types)
* [`no-types-missing-file-annotation`](#eslint-plugin-flowtype-rules-no-types-missing-file-annotation)
* [`no-unused-expressions`](#eslint-plugin-flowtype-rules-no-unused-expressions)
* [`no-weak-types`](#eslint-plugin-flowtype-rules-no-weak-types)
* [`object-type-curly-spacing`](#eslint-plugin-flowtype-rules-object-type-curly-spacing)
* [`object-type-delimiter`](#eslint-plugin-flowtype-rules-object-type-delimiter)
* [`quotes`](#eslint-plugin-flowtype-rules-quotes)
* [`require-compound-type-alias`](#eslint-plugin-flowtype-rules-require-compound-type-alias)
* [`require-exact-type`](#eslint-plugin-flowtype-rules-require-exact-type)
* [`require-indexer-name`](#eslint-plugin-flowtype-rules-require-indexer-name)
* [`require-inexact-type`](#eslint-plugin-flowtype-rules-require-inexact-type)
* [`require-parameter-type`](#eslint-plugin-flowtype-rules-require-parameter-type)
* [`require-readonly-react-props`](#eslint-plugin-flowtype-rules-require-readonly-react-props)
* [`require-return-type`](#eslint-plugin-flowtype-rules-require-return-type)
* [`require-types-at-top`](#eslint-plugin-flowtype-rules-require-types-at-top)
* [`require-valid-file-annotation`](#eslint-plugin-flowtype-rules-require-valid-file-annotation)
* [`require-variable-type`](#eslint-plugin-flowtype-rules-require-variable-type)
* [`semi`](#eslint-plugin-flowtype-rules-semi)
* [`sort-keys`](#eslint-plugin-flowtype-rules-sort-keys)
* [`sort-type-union-intersection-members`](#eslint-plugin-flowtype-rules-sort-type-union-intersection-members)
* [`space-after-type-colon`](#eslint-plugin-flowtype-rules-space-after-type-colon)
* [`space-before-generic-bracket`](#eslint-plugin-flowtype-rules-space-before-generic-bracket)
* [`space-before-type-colon`](#eslint-plugin-flowtype-rules-space-before-type-colon)
* [`spread-exact-type`](#eslint-plugin-flowtype-rules-spread-exact-type)
* [`type-id-match`](#eslint-plugin-flowtype-rules-type-id-match)
* [`type-import-style`](#eslint-plugin-flowtype-rules-type-import-style)
* [`union-intersection-spacing`](#eslint-plugin-flowtype-rules-union-intersection-spacing)
* [`use-flow-type`](#eslint-plugin-flowtype-rules-use-flow-type)
* [`use-read-only-spread`](#eslint-plugin-flowtype-rules-use-read-only-spread)
* [`valid-syntax`](#eslint-plugin-flowtype-rules-valid-syntax)
<a name="eslint-plugin-flowtype-installation"></a>
## Installation
```bash
npm install eslint --save-dev
npm install @babel/eslint-parser --save-dev
npm install eslint-plugin-flowtype --save-dev
```
<a name="eslint-plugin-flowtype-configuration"></a>
## Configuration
1. Set `parser` property to `@babel/eslint-parser`.
1. Add `plugins` section and specify `eslint-plugin-flowtype` as a plugin.
1. Enable rules.
<!-- -->
```json
{
"parser": "@babel/eslint-parser",
"plugins": [
"flowtype"
],
"rules": {
"flowtype/boolean-style": [
2,
"boolean"
],
"flowtype/define-flow-type": 1,
"flowtype/delimiter-dangle": [
2,
"never"
],
"flowtype/generic-spacing": [
2,
"never"
],
"flowtype/interface-id-match": [
2,
"^([A-Z][a-z0-9]+)+Type$"
],
"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]+)+Type$"
],
"flowtype/union-intersection-spacing": [
2,
"always"
],
"flowtype/use-flow-type": 1,
"flowtype/valid-syntax": 1
},
"settings": {
"flowtype": {
"onlyFilesWithFlowAnnotation": false
}
}
}
```
<a name="eslint-plugin-flowtype-configuration-shareable-configurations"></a>
### Shareable configurations
<a name="eslint-plugin-flowtype-configuration-shareable-configurations-recommended"></a>
#### Recommended
This plugin exports a [recommended configuration](./src/configs/recommended.json) that enforces Flow type good practices.
To enable this configuration use the extends property in your `.eslintrc` config file:
```json
{
"extends": [
"plugin:flowtype/recommended"
],
"plugins": [
"flowtype"
]
}
```
See [ESLint documentation](http://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information about extending configuration files.
<a name="eslint-plugin-flowtype-configuration-community-maintained-configurations"></a>
### Community maintained configurations
The following are third-party submitted/ maintained configurations of `eslint-plugin-flowtype`:
* https://github.com/wemake-services/eslint-config-flowtype-essential
<a name="eslint-plugin-flowtype-settings"></a>
## Settings
<a name="eslint-plugin-flowtype-settings-onlyfileswithflowannotation"></a>
### <code>onlyFilesWithFlowAnnotation</code>
When `true`, only checks files with a [`@flow` annotation](http://flowtype.org/docs/about-flow.html#gradual) in the first comment.
```js
{
"settings": {
"flowtype": {
"onlyFilesWithFlowAnnotation": true
}
}
}
```
<a name="eslint-plugin-flowtype-rules"></a>
## Rules
<!-- Rules are sorted alphabetically. -->
<a name="eslint-plugin-flowtype-rules-array-style-complex-type"></a>
### <code>array-style-complex-type</code>
_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:
* [Maybe type](https://flow.org/en/docs/types/maybe/)
* [Function type](https://flow.org/en/docs/types/functions/)
* [Object type](https://flow.org/en/docs/types/objects/)
* [Tuple type](https://flow.org/en/docs/types/tuples/)
* [Union type](https://flow.org/en/docs/types/unions/)
* [Intersection type](https://flow.org/en/docs/types/intersections/)
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:
```js
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:
```js
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>
```
<a name="eslint-plugin-flowtype-rules-array-style-simple-type"></a>
### <code>array-style-simple-type</code>
_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:
* [Primitive types](https://flow.org/en/docs/types/primitives/)
* [Literal types](https://flow.org/en/docs/types/literals/)
* [Mixed type](https://flow.org/en/docs/types/mixed/)
* [Any type](https://flow.org/en/docs/types/any/)
* [Class type](https://flow.org/en/docs/types/classes/)
* [Generic type](https://flow.org/en/docs/types/generics/)
* Array type [shorthand notation](https://flow.org/en/docs/types/arrays/#toc-array-type-shorthand-syntax)
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:
```js
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 = 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:
```js
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
```
<a name="eslint-plugin-flowtype-rules-arrow-parens"></a>
### <code>arrow-parens</code>
_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:
```js
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:
```js
() => {}
(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"
```
<a name="eslint-plugin-flowtype-rules-boolean-style"></a>
### <code>boolean-style</code>
_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:
```js
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:
```js
type X = boolean
// Options: ["boolean"]
type X = boolean
// Options: ["bool"]
type X = bool
// Options: ["boolean"]
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
type X = bool
```
<a name="eslint-plugin-flowtype-rules-define-flow-type"></a>
### <code>define-flow-type</code>
Marks Flow type identifiers as defined.
Used to suppress [`no-undef`](http://eslint.org/docs/rules/no-undef) reporting of type identifiers.
The following patterns are not considered problems:
```js
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"]}
```
<a name="eslint-plugin-flowtype-rules-delimiter-dangle"></a>
### <code>delimiter-dangle</code>
_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:
```js
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:
```js
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 = []
```
<a name="eslint-plugin-flowtype-rules-enforce-line-break"></a>
### <code>enforce-line-break</code>
This rule enforces line breaks between type definitions.
The following patterns are considered problems:
```js
type baz = 6;
const hi = 2;
// Message: New line required below type declaration
const foo = 6;
type hi = 2;
// Message: New line required above type declaration
const som = "jes";
// a comment
type fed = "hed";
// Message: New line required above type declaration
type som = "jes";
// a comment
const fed = "hed";
// Message: New line required below type declaration
type hello = 34;
const som = "jes";
type fed = "hed";
// Message: New line required below type declaration
// Message: New line required above type declaration
const a = 5;
export type hello = 34;
// Message: New line required above type declaration
const a = 5;
// a comment
export type hello = 34;
// Message: New line required above type declaration
const a = 5;
/**
* a jsdoc block
*/
type hello = 34;
// Message: New line required above type declaration
```
The following patterns are not considered problems:
```js
type gjs = 6;
type gjs = 6;
type hi = 2;
type X = 4;
const red = "serpent";
console.log("hello");
// number or string
type Y = string | number;
// resting + sleep
type snooze = "dreaming" | "";
type Props = {
accountBalance: string | number,
accountNumber: string | number,
};
const x = 4;
const y = 489;
// Some Comment
type Props = {
accountBalance: string | number,
accountNumber: string | number,
};
type RoadT = "grass" | "gravel" | "cement";
// @flow
type A = string
```
<a name="eslint-plugin-flowtype-rules-generic-spacing"></a>
### <code>generic-spacing</code>
_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:
```js
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:
```js
type X = Promise<string>
type X = Promise<(string)>
type X = Promise<(foo), bar, (((baz)))>
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))) >
```
<a name="eslint-plugin-flowtype-rules-interface-id-match"></a>
### <code>interface-id-match</code>
Enforces a consistent naming pattern for interfaces.
<a name="eslint-plugin-flowtype-rules-interface-id-match-options"></a>
#### Options
This rule requires a text RegExp:
```js
{
"rules": {
"flowtype/interface-id-match": [
2,
"^([A-Z][a-z0-9]*)+Type$"
]
}
}
```
`'^([A-Z][a-z0-9]*)+Type$$'` is the default pattern.
The following patterns are considered problems:
```js
interface foo{};
// Message: Interface identifier 'foo' does not match pattern '/^([A-Z][a-z0-9]*)+Type$/u'.
// Options: ["^foo$"]
interface FooType{};
// Message: Interface identifier 'FooType' does not match pattern '/^foo$/u'.
```
The following patterns are not considered problems:
```js
interface FooType {};
// Options: ["^foo$"]
interface foo {};
// Settings: {"flowtype":{"onlyFilesWithFlowAnnotation":true}}
interface foo {};
```
<a name="eslint-plugin-flowtype-rules-newline-after-flow-annotation"></a>
### <code>newline-after-flow-annotation</code>
This rule requires an empty line after the Flow annotation.
<a name="eslint-plugin-flowtype-rules-newline-after-flow-annotation-options-1"></a>
#### 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
```js
{
"rules": {
"flowtype/newline-after-flow-annotation": [
2,
"always"
]
}
}
```
The following patterns are considered problems:
```js
// @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:
```js
// Options: ["always"]
// @flow
import Foo from './foo';
// Options: ["always-windows"]
// @flow
import Foo from './foo';
// Options: ["never"]
// @flow
import Foo from './foo';
```
<a name="eslint-plugin-flowtype-rules-no-dupe-keys"></a>
### <code>no-dupe-keys</code>
Checks for duplicate properties in Object annotations.
This rule mirrors ESLint's [no-dupe-keys](http://eslint.org/docs/rules/no-dupe-keys) rule.
```js
{
"rules": {
"flowtype/no-dupe-keys": 2
}
}
```
The following patterns are considered problems:
```js
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:
```js
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; }
```
<a name="eslint-plugin-flowtype-rules-no-duplicate-type-union-intersection-members"></a>
### <code>no-duplicate-type-union-intersection-members</code>
_The `--fix` option on the command line automatically fixes problems reported by this rule._
Checks for duplicate members of a type union/intersection.
<a name="eslint-plugin-flowtype-rules-no-duplicate-type-union-intersection-members-options-2"></a>
#### Options
You can disable checking intersection types using `checkIntersections`.
* `true` (default) - check for duplicate members of intersection members.
* `false` - do not check for duplicate members of intersection members.
```js
{
"rules": {
"flowtype/no-duplicate-type-union-intersection-members": [
2,
{
"checkIntersections": true
}
]
}
}
```
You can disable checking union types using `checkUnions`.
* `true` (default) - check for duplicate members of union members.
* `false` - do not check for duplicate members of union members.
```js
{
"rules": {
"flowtype/no-duplicate-type-union-intersection-members": [
2,
{
"checkUnions": true
}
]
}
}
```
The following patterns are considered problems:
```js
type A = 1 | 2 | 3 | 1;
// Message: Duplicate union member found "1".
type B = 'foo' | 'bar' | 'foo';
/