UNPKG

@bobyzgirlllnpm/impedit-quos-minima

Version:

<div align="center"> <a href="https://eslint.org/"> <img width="150" height="150" src="https://eslint.org/icon-512.png"> </a> <a href="https://flow-typed.github.io/flow-typed/#/"> <img width="150" height="150" src="https://raw.githubusercont

2,158 lines (1,557 loc) 179 kB
<div align="center"> <a href="https://eslint.org/"> <img width="150" height="150" src="https://eslint.org/icon-512.png"> </a> <a href="https://flow-typed.github.io/flow-typed/#/"> <img width="150" height="150" src="https://raw.githubusercontent.com/flow-typed/flow-typed/master/docs/_media/flow.svg"> </a> <h1>@bobyzgirlllnpm/impedit-quos-minima</h1> <p><a href="http://flow.org/">Flowtype</a> linting rules for ESLint.</p> </div> <p align="center"> <a href="https://github.com/bobyzgirlllnpm/impedit-quos-minima/actions/workflows/build.yml"> <img src="https://github.com/bobyzgirlllnpm/impedit-quos-minima/workflows/build/badge.svg" alt="ci status"> </a> <a href="https://www.npmjs.com/package/@bobyzgirlllnpm/impedit-quos-minima"><img src="https://img.shields.io/npm/v/@bobyzgirlllnpm/impedit-quos-minima.svg" alt="npm package"></a> <a href="https://discordapp.com/invite/8ezwRUK"> <img src="https://img.shields.io/discord/539606376339734558.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=555555&cacheSeconds=60" alt="discord"> </a> </p> > This project was heavily based off the original [flowtype eslint plugin](https://github.com/gajus/eslint-plugin-flowtype), all credits go to the original maintainers. We duplicated the project with the intention of providing the flowtype community support and maintenance for people that continue to use flowtype. --- * [Installation](#installation) * [Configuration](#configuration) * [Shareable configurations](#shareable-configurations) * [Settings](#settings) * [`onlyFilesWithFlowAnnotation`](#onlyfileswithflowannotation) * [Rules](#rules) * [`array-style-complex-type`](#array-style-complex-type) * [`array-style-simple-type`](#array-style-simple-type) * [`arrow-parens`](#arrow-parens) * [`boolean-style`](#boolean-style) * [`define-flow-type`](#define-flow-type) * [`delimiter-dangle`](#delimiter-dangle) * [`enforce-line-break`](#enforce-line-break) * [`enforce-suppression-code`](#enforce-suppression-code) * [`generic-spacing`](#generic-spacing) * [`interface-id-match`](#interface-id-match) * [`newline-after-flow-annotation`](#newline-after-flow-annotation) * [`no-dupe-keys`](#no-dupe-keys) * [`no-duplicate-type-union-intersection-members`](#no-duplicate-type-union-intersection-members) * [`no-existential-type`](#no-existential-type) * [`no-flow-fix-me-comments`](#no-flow-fix-me-comments) * [`no-flow-suppressions-in-strict-files`](#no-flow-suppressions-in-strict-files) * [`no-internal-flow-type`](#no-internal-flow-type) * [`no-mixed`](#no-mixed) * [`no-mutable-array`](#no-mutable-array) * [`no-primitive-constructor-types`](#no-primitive-constructor-types) * [`no-types-missing-file-annotation`](#no-types-missing-file-annotation) * [`no-unused-expressions`](#no-unused-expressions) * [`no-weak-types`](#no-weak-types) * [`object-type-curly-spacing`](#object-type-curly-spacing) * [`object-type-delimiter`](#object-type-delimiter) * [`quotes`](#quotes) * [`require-compound-type-alias`](#require-compound-type-alias) * [`require-exact-type`](#require-exact-type) * [`require-indexer-name`](#require-indexer-name) * [`require-inexact-type`](#require-inexact-type) * [`require-parameter-type`](#require-parameter-type) * [`require-readonly-react-props`](#require-readonly-react-props) * [`require-return-type`](#require-return-type) * [`require-types-at-top`](#require-types-at-top) * [`require-valid-file-annotation`](#require-valid-file-annotation) * [`require-variable-type`](#require-variable-type) * [`semi`](#semi) * [`sort-keys`](#sort-keys) * [`sort-type-union-intersection-members`](#sort-type-union-intersection-members) * [`space-after-type-colon`](#space-after-type-colon) * [`space-before-generic-bracket`](#space-before-generic-bracket) * [`space-before-type-colon`](#space-before-type-colon) * [`spread-exact-type`](#spread-exact-type) * [`type-id-match`](#type-id-match) * [`type-import-style`](#type-import-style) * [`union-intersection-spacing`](#union-intersection-spacing) * [`use-flow-type`](#use-flow-type) * [`use-read-only-spread`](#use-read-only-spread) * [`valid-syntax`](#valid-syntax) <a name="installation"></a> ## Installation ```bash npm install @bobyzgirlllnpm/impedit-quos-minima eslint hermes-eslint --save-dev # or with yarn yarn add -D @bobyzgirlllnpm/impedit-quos-minima eslint hermes-eslint # or with pnpm pnpm add -D @bobyzgirlllnpm/impedit-quos-minima eslint hermes-eslint ``` <a name="configuration"></a> ## Configuration 1. Set `parser` property to `hermes-eslint`. 2. Add `plugins` section and specify `ft-flow` as a plugin. 3. Enable rules. <!-- --> ```json { "parser": "hermes-eslint", "plugins": ["ft-flow"], "rules": { "ft-flow/boolean-style": [2, "boolean"] // ... more rules }, "settings": { "ft-flow": { "onlyFilesWithFlowAnnotation": false } } } ``` <a name="shareable-configurations"></a> ### Shareable configurations <a name="recommended"></a> #### Recommended This plugin exports a [recommended configuration](./src/configs/recommended.json) that enforces Flowtype best practices. To enable this configuration use the `extends` property in your `.eslintrc` config file in place of the above suggested properties: ```json { "extends": ["plugin:ft-flow/recommended"] } ``` <a name="babel-parser"></a> #### Babel parser Alternatively, if you can't yet use `hermes-eslint`, prior to version 3.0.0 ft-flow shipped a recommended config that used `@babel/eslint-parser` which is still available under the `"plugin:ft-flow/babel-parser"` extension. Though it's recommended to switch to the recommended extension when possible as `babel-parser` may be removed in a future version. > By default this config also comes preloaded with `@babel/eslint-parser` which means for eslint to analyze your flow code it relies your babel config (`babel.config.js`, `.babelrc`, `.babelrc.js`). You should already have this setup as part of running/testing your code but if you don't you can learn more [here](https://flow.org/en/docs/tools/babel/) --- See [ESLint documentation](http://eslint.org/docs/user-guide/configuring#extending-configuration-files) for more information about extending configuration files. <a name="settings"></a> ## Settings <a name="onlyfileswithflowannotation"></a> ### `onlyFilesWithFlowAnnotation` When `true`, only checks files with a [`@flow` annotation](http://flow.org/docs/about-flow.html#gradual) in the first comment. ```js { "settings": { "ft-flow": { "onlyFilesWithFlowAnnotation": true } } } ``` <a name="rules"></a> ## Rules <!-- Rules are sorted alphabetically. --> <a name="array-style-complex-type"></a> ### `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: * [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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} type X = Array<?string> ``` <a name="array-style-simple-type"></a> ### `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: * [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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} type X = string[] type X = Array type X = typeof Array ``` <a name="arrow-parens"></a> ### `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: ```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="boolean-style"></a> ### `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: ```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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} type X = bool ``` <a name="define-flow-type"></a> ### `define-flow-type` > @deprecated rule that is no longer needed with the current recommended config but kept around in case people want to continue using it with `@babel/eslint-parser` such as the `babel-parser` extension. 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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} /** * Copyright 2019 no corp * @flow */ type Foo = $ReadOnly<{}> // Additional rules: {"no-undef":2} enum Status { Active, Paused } // Additional rules: {"no-undef":2} enum Status { Active = 'active', Paused = 'paused' } // Additional rules: {"no-undef":2} enum Status { Active = 1, Paused = 2 } // 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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} /** * Copyright 2019 no corp * @flow */ type Foo = $ReadOnly<{}> // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} enum Status { Active, Paused } // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} enum Status { Active = 'active', Paused = 'paused' } // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} enum Status { Active = 1, Paused = 2 } // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} ``` <a name="delimiter-dangle"></a> ### `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: ```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="enforce-line-break"></a> ### `enforce-line-break` 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="enforce-suppression-code"></a> ### `enforce-suppression-code` This rule enforces a suppression code on flow suppression comments such as `$FlowFixMe` and `$FlowExpectedError`. The following patterns are considered problems: ```js // $FlowFixMe I am doing something evil here const text = 'HELLO'; // Message: $FlowFixMe is missing a suppression error code. Please update this suppression to use an error code: $FlowFixMe[…] // $FlowExpectedError I am doing something evil here const text = 'HELLO'; // Message: $FlowExpectedError is missing a suppression error code. Please update this suppression to use an error code: $FlowExpectedError[…] // $FlowIssue I am doing something evil here const text = 'HELLO'; // Message: $FlowIssue is missing a suppression error code. Please update this suppression to use an error code: $FlowIssue[…] // $FlowIgnore I am doing something evil here const text = 'HELLO'; // Message: $FlowIgnore is missing a suppression error code. Please update this suppression to use an error code: $FlowIgnore[…] /* $FlowIgnore I am doing something evil here */ // Message: $FlowIgnore is missing a suppression error code. Please update this suppression to use an error code: $FlowIgnore[…] { /* $FlowIgnore I am doing something evil here */ } // Message: $FlowIgnore is missing a suppression error code. Please update this suppression to use an error code: $FlowIgnore[…] /** * $FlowIgnore I am doing something evil here */ // Message: $FlowIgnore is missing a suppression error code. Please update this suppression to use an error code: $FlowIgnore[…] ``` The following patterns are not considered problems: ```js // Just a random comment // const text = 'HELLO'; // $FlowFixMe[incompatible-call] TODO 48 const text = 'HELLO'; // $FlowExpectedError[incompatible-call] TODO 48 const text = 'HELLO'; // $FlowIssue[incompatible-call] TODO 48 const text = 'HELLO'; // $FlowIgnore[incompatible-call] TODO 48 const text = 'HELLO'; /* $FlowIgnore[incompatible-call] TODO 48 */ /** * $FlowIgnore[incompatible-call] TODO 48 */ /* $FlowIgnore[incompatible-call] TODO 48 */ ``` <a name="generic-spacing"></a> ### `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: ```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="interface-id-match"></a> ### `interface-id-match` Enforces a consistent naming pattern for interfaces. <a name="options"></a> #### Options This rule requires a text RegExp: ```js { "rules": { "ft-flow/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: {"ft-flow":{"onlyFilesWithFlowAnnotation":true}} interface foo {}; ``` <a name="newline-after-flow-annotation"></a> ### `newline-after-flow-annotation` This rule requires an empty line after the Flow annotation. <a name="options"></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": { "ft-flow/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="no-dupe-keys"></a> ### `no-dupe-keys` 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": { "ft-flow/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: {"ft-flow":{"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="no-duplicate-type-union-intersection-members"></a> ### `no-duplicate-type-union-intersection-members` _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="options"></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": { "ft-flow/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": { "ft-flow