pax_global_header00006660000000000000000000000064130037530330014507gustar00rootroot0000000000000052 comment=8f355c2b6e37ee391e35c8283ba879591f69a8c9 eslint-plugin-flowtype-2.25.0/000077500000000000000000000000001300375303300162365ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/.README/000077500000000000000000000000001300375303300172515ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/.README/README.md000066400000000000000000000105541300375303300205350ustar00rootroot00000000000000# eslint-plugin-flowtype [![NPM version](http://img.shields.io/npm/v/eslint-plugin-flowtype.svg?style=flat-square)](https://www.npmjs.org/package/eslint-plugin-flowtype) [![Travis build status](http://img.shields.io/travis/gajus/eslint-plugin-flowtype/master.svg?style=flat-square)](https://travis-ci.org/gajus/eslint-plugin-flowtype) [![js-canonical-style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](https://github.com/gajus/canonical) [Flow type](http://flowtype.org/) linting rules for ESLint. {"gitdown": "contents"} ## Installation 1. Install [ESLint](https://www.github.com/eslint/eslint). 1. Install [`babel-eslint`](https://github.com/babel/babel-eslint) parser (ESLint parser [does not support type annotations](https://github.com/eslint/eslint/issues/2157)). 1. Install [`eslint-plugin-flowtype`](https://github.com/gajus/eslint-plugin-flowtype) plugin. ```sh npm install eslint npm install babel-eslint npm install eslint-plugin-flowtype ``` ## Configuration 1. Set `parser` property to `babel-eslint`. 1. Add `plugins` section and specify `eslint-plugin-flowtype` as a plugin. 1. Enable rules. ```json { "parser": "babel-eslint", "plugins": [ "flowtype" ], "rules": { "flowtype/boolean-style": [ 2, "boolean" ], "flowtype/define-flow-type": 1, "flowtype/delimiter-dangle": [ 2, "never" ], "flowtype/generic-spacing": [ 2, "never" ], "flowtype/no-weak-types": 2, "flowtype/object-type-delimiter": [ 2, "comma" ], "flowtype/require-parameter-type": 2, "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 } } } ``` ### Shareable configurations #### 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. ## Settings ### `onlyFilesWithFlowAnnotation` 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 } } } ``` ## Rules {"gitdown": "include", "file": "./rules/boolean-style.md"} {"gitdown": "include", "file": "./rules/define-flow-type.md"} {"gitdown": "include", "file": "./rules/delimiter-dangle.md"} {"gitdown": "include", "file": "./rules/generic-spacing.md"} {"gitdown": "include", "file": "./rules/no-dupe-keys.md"} {"gitdown": "include", "file": "./rules/no-weak-types.md"} {"gitdown": "include", "file": "./rules/object-type-delimiter.md"} {"gitdown": "include", "file": "./rules/require-parameter-type.md"} {"gitdown": "include", "file": "./rules/require-return-type.md"} {"gitdown": "include", "file": "./rules/require-valid-file-annotation.md"} {"gitdown": "include", "file": "./rules/semi.md"} {"gitdown": "include", "file": "./rules/sort-keys.md"} {"gitdown": "include", "file": "./rules/space-after-type-colon.md"} {"gitdown": "include", "file": "./rules/space-before-generic-bracket.md"} {"gitdown": "include", "file": "./rules/space-before-type-colon.md"} {"gitdown": "include", "file": "./rules/type-id-match.md"} {"gitdown": "include", "file": "./rules/union-intersection-spacing.md"} {"gitdown": "include", "file": "./rules/use-flow-type.md"} {"gitdown": "include", "file": "./rules/valid-syntax.md"} eslint-plugin-flowtype-2.25.0/.README/rules/000077500000000000000000000000001300375303300204035ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/.README/rules/boolean-style.md000066400000000000000000000006731300375303300235100ustar00rootroot00000000000000### `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'`. eslint-plugin-flowtype-2.25.0/.README/rules/define-flow-type.md000066400000000000000000000003111300375303300240760ustar00rootroot00000000000000### `define-flow-type` Marks Flow type identifiers as defined. Used to suppress [`no-undef`](http://eslint.org/docs/rules/no-undef) reporting of type identifiers. eslint-plugin-flowtype-2.25.0/.README/rules/delimiter-dangle.md000066400000000000000000000015441300375303300241370ustar00rootroot00000000000000### `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 one argument which mirrors ESLint's default `comma-dangle` rule. 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 default value is `'never'`. eslint-plugin-flowtype-2.25.0/.README/rules/generic-spacing.md000066400000000000000000000007701300375303300237670ustar00rootroot00000000000000### `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'`. eslint-plugin-flowtype-2.25.0/.README/rules/no-dupe-keys.md000066400000000000000000000004161300375303300232460ustar00rootroot00000000000000### `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": { "flowtype/no-dupe-keys": 2 } } ``` eslint-plugin-flowtype-2.25.0/.README/rules/no-weak-types.md000066400000000000000000000015051300375303300234310ustar00rootroot00000000000000### `no-weak-types` Warns against weak type annotations *any*, *Object* and *Function*. These types can cause flow to silently skip over portions of your code, which would have otherwise caused type errors. This rule optionally takes one argument, an object to configure which type warnings to enable. By default, all of the warnings are enabled. e.g. to disable the `any` warning (allowing it to exist in your code), while continuing to warn about `Object` and `Function`: ```js { "rules": { "flowtype/no-weak-types": [2, { "any": false, "Object": true, "Function": true }] } } // or, the following is equivalent as default is true: { "rules": { "flowtype/no-weak-types": [2, { "any": false }] } } ``` eslint-plugin-flowtype-2.25.0/.README/rules/object-type-delimiter.md000066400000000000000000000010461300375303300251270ustar00rootroot00000000000000### `object-type-delimiter` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent separators between properties in Flow object types. This rule takes one argument. If it is `'comma'` then a problem is raised when using `;` as a separator. If it is `'semicolon'` then a problem is raised when using `,` as a separator. The default value is `'comma'`. _This rule is ported from `babel/flow-object-type`, however the default option was changed._ eslint-plugin-flowtype-2.25.0/.README/rules/require-parameter-type.md000066400000000000000000000022371300375303300253420ustar00rootroot00000000000000### `require-parameter-type` Requires that all function parameters have type annotations. #### Options You can skip all arrow functions by providing the `excludeArrowFunctions` option with `true`. Alternatively, you can want to exclude only concise arrow functions (e.g. `x => x * 2`). Provide `excludeArrowFunctions` with `expressionsOnly` for this. ```js { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeArrowFunctions": true } ] } } { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeArrowFunctions": "expressionsOnly" } ] } } ``` You can exclude parameters that match a certain regex by using `excludeParameterMatch`. ```js { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeParameterMatch": "^_" } ] } } ``` This excludes all parameters that start with an underscore (`_`). The default pattern is `a^`, which doesn't match anything, i.e., all parameters are checked. eslint-plugin-flowtype-2.25.0/.README/rules/require-return-type.md000066400000000000000000000014101300375303300246710ustar00rootroot00000000000000### `require-return-type` Requires that functions have return type annotation. #### Options You can skip all arrow functions by providing the `excludeArrowFunctions` option with `true`. Alternatively, you can want to exclude only concise arrow function (e.g. `() => 2`). Provide `excludeArrowFunctions` with `expressionsOnly` for this. ```js { "rules": { "flowtype/require-return-type": [ 2, "always", { "excludeArrowFunctions": true } ] } } { "rules": { "flowtype/require-return-type": [ 2, "always", { "excludeArrowFunctions": "expressionsOnly" } ] } } ``` eslint-plugin-flowtype-2.25.0/.README/rules/require-valid-file-annotation.md000066400000000000000000000020051300375303300265600ustar00rootroot00000000000000### `require-valid-file-annotation` This rule validates Flow file annotations. This rule can optionally report missing or missed placed annotations, common typos (e.g. `// @floww`), and enforce a consistant annotation style. #### Options The rule has a string option: * `"never"` (default): Never report files that are missing an `@flow` annotation. * `"always"`: Always report files that are missing an `@flow` annotation This rule has an object option: * `"annotationStyle"` - Enforce a consistant file annotation style. * `"none"` (default): Either annotation style is accepted. * `"line"`: Require single line annotations (i.e. `// @flow`). * `"block"`: Require block annotations (i.e. `/* @flow */`). ```js { "rules": { "flowtype/require-valid-file-annotation": [ 2, "always" ] } } { "rules": { "flowtype/require-valid-file-annotation": [ 2, "always", { "annotationStyle": "block" } ] } } ``` eslint-plugin-flowtype-2.25.0/.README/rules/semi.md000066400000000000000000000006651300375303300216710ustar00rootroot00000000000000### `semi` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent use of semicolons after type aliases. This rule takes one argument. If it is `'never'` then a problem is raised when there is a semicolon after a type alias. If it is `'always'` then a problem is raised when there is no semicolon after a type alias. The default value is `'always'`. eslint-plugin-flowtype-2.25.0/.README/rules/sort-keys.md000066400000000000000000000013621300375303300226670ustar00rootroot00000000000000### `sort-keys` Enforces sorting of Object annotations. This rule mirrors ESlint's [sort-keys](http://eslint.org/docs/rules/sort-keys) rule. #### Options The first option specifies sort order. * `"asc"` (default) - enforce ascending sort order. * `"desc"` - enforce descending sort order. The second option takes an object with two possible properties. * `caseSensitive` - if `true`, enforce case-sensitive sort order. Default is `true`. * `natural` - if `true`, enforce [natural sort order](https://en.wikipedia.org/wiki/Natural_sort_order). Default is `false`. ```js { "rules": { "flowtype/sort-keys": [ 2, "asc", { "caseSensitive": true, "natural": false } ] } } ``` eslint-plugin-flowtype-2.25.0/.README/rules/space-after-type-colon.md000066400000000000000000000007521300375303300252120ustar00rootroot00000000000000### `space-after-type-colon` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing after the type annotation colon. This rule takes one argument. If it is `'always'` then a problem is raised when there is no space after the type annotation colon. If it is `'never'` then a problem is raised when there is a space after the type annotation colon. The default value is `'always'`. eslint-plugin-flowtype-2.25.0/.README/rules/space-before-generic-bracket.md000066400000000000000000000007611300375303300263070ustar00rootroot00000000000000### `space-before-generic-bracket` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing before the opening `<` of generic type annotation parameters. This rule takes one argument. If it is `'never'` then a problem is raised when there is a space before the `<`. If it is `'always'` then a problem is raised when there is no space before the `<`. The default value is `'never'`. eslint-plugin-flowtype-2.25.0/.README/rules/space-before-type-colon.md000066400000000000000000000007561300375303300253570ustar00rootroot00000000000000### `space-before-type-colon` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing before the type annotation colon. This rule takes one argument. If it is `'always'` then a problem is raised when there is no space before the type annotation colon. If it is `'never'` then a problem is raised when there is a space before the type annotation colon. The default value is `'never'`. eslint-plugin-flowtype-2.25.0/.README/rules/type-id-match.md000066400000000000000000000006041300375303300233720ustar00rootroot00000000000000### `type-id-match` Enforces a consistent naming pattern for type aliases. #### Options This rule needs a text RegExp to operate with Its signature is as follows: ```js { "rules": { "flowtype/type-id-match": [ 2, "^([A-Z][a-z0-9]*)+Type$" ] } } ``` `'^([A-Z][a-z0-9]*)+Type$$'` is the default pattern. eslint-plugin-flowtype-2.25.0/.README/rules/union-intersection-spacing.md000066400000000000000000000007721300375303300262110ustar00rootroot00000000000000### `union-intersection-spacing` _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing around union and intersection type separators (`|` and `&`). This rule takes one argument. If it is `'always'` then a problem is raised when there is no space around the separator. If it is `'never'` then a problem is raised when there is a space around the separator. The default value is `'always'`. eslint-plugin-flowtype-2.25.0/.README/rules/use-flow-type.md000066400000000000000000000004161300375303300234460ustar00rootroot00000000000000### `use-flow-type` Marks Flow [type alias](https://flowtype.org/docs/type-aliases.html) declarations as used. Used to suppress [`no-unused-vars`](http://eslint.org/docs/rules/no-unused-vars) errors that are triggered by type aliases. eslint-plugin-flowtype-2.25.0/.README/rules/valid-syntax.md000066400000000000000000000002551300375303300233520ustar00rootroot00000000000000### `valid-syntax` **Deprecated** Babylon (the Babel parser) v6.10.0 fixes parsing of the invalid syntax this plugin warned against. Checks for simple Flow syntax errors. eslint-plugin-flowtype-2.25.0/.babelrc000066400000000000000000000001641300375303300176320ustar00rootroot00000000000000{ "presets": [ "es2015", "stage-0" ], "plugins": [ "add-module-exports" ] } eslint-plugin-flowtype-2.25.0/.eslintrc000066400000000000000000000000371300375303300200620ustar00rootroot00000000000000{ "extends": "canonical" } eslint-plugin-flowtype-2.25.0/.gitignore000077500000000000000000000001611300375303300202270ustar00rootroot00000000000000node_modules coverage dist *.log .* !.eslintrc !.gitignore !.npmignore !.babelrc !.travis.yml !.README !.scripts eslint-plugin-flowtype-2.25.0/.npmignore000077500000000000000000000000341300375303300202350ustar00rootroot00000000000000src tests coverage .* *.log eslint-plugin-flowtype-2.25.0/.scripts/000077500000000000000000000000001300375303300200035ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/.scripts/release.sh000077500000000000000000000027711300375303300217710ustar00rootroot00000000000000#!/bin/bash set -ex if [[ $TRAVIS_PULL_REQUEST != "false" ]]; then echo 'This is a pull request. Exiting the release script.' exit 0 fi if [[ -n $TRAVIS_TAG ]]; then echo 'This is a tag release.' # Use NPM_TOKEN to enable NPM authentication set +x echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > ~/.npmrc set -x NODE_ENV=development npm install NODE_ENV=production npm run build npm publish exit 0 fi if [[ $TRAVIS_BRANCH != "master" ]]; then echo 'This is not a master branch. Exiting the release script.' exit 0 fi if [[ $(git log --format=%B -n 1 $TRAVIS_COMMIT) == *"chore: release"* ]]; then echo 'This is a tag release. Exiting the release script.' exit 0 fi; git config --global user.name 'continuous-deployment' git config --global user.email 'continuous-deployment@travis' # Use GITHUB_TOKEN to enable GitHub authentication git config credential.helper "store --file=.git/credentials" set +x echo "https://${GITHUB_TOKEN}:@github.com" > .git/credentials set -x git checkout master git merge $TRAVIS_COMMIT # Generate ./README.md from ./.README/README.md template. npm run documentation git add ./README.md git diff-index --quiet HEAD ./README.md || git commit --no-verify -m 'docs: update documentation' ./README.md # 1. bump the package.json version (based on your commit history) # 2. update CHANGELOG.md # 3. commit package.json and CHANGELOG.md # 4. tag the release standard-version --no-verify --message "chore: release %s" git push --follow-tags origin master eslint-plugin-flowtype-2.25.0/.travis.yml000066400000000000000000000005661300375303300203560ustar00rootroot00000000000000language: node_js node_js: - 6 - 5 - 4 before_install: - npm config set depth 0 - npm install --global npm@3 notifications: email: false sudo: false script: - npm run test - npm run lint - npm run build - conventional-changelog-lint --from=HEAD~$(git --no-pager rev-list master..HEAD --count) after_success: - travis-after-all && ./.scripts/release.sh eslint-plugin-flowtype-2.25.0/CHANGELOG.md000066400000000000000000000176111300375303300200550ustar00rootroot00000000000000# Change Log All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. # [2.25.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.24.0...v2.25.0) (2016-10-25) ### Features * Add excludeParameterMatch option to require-parameter-type ([d9cfbbe](https://github.com/gajus/eslint-plugin-flowtype/commit/d9cfbbe)) # [2.24.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.23.1...v2.24.0) (2016-10-25) ### Features * add additional tests for function return types ([795b3a4](https://github.com/gajus/eslint-plugin-flowtype/commit/795b3a4)) ## [2.23.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.23.0...v2.23.1) (2016-10-25) ### Bug Fixes * Support more properties in object-type-delimiter ([6b0a677](https://github.com/gajus/eslint-plugin-flowtype/commit/6b0a677)) # [2.23.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.22.0...v2.23.0) (2016-10-24) ### Features * add object-type-delimiter rule ([a99721b](https://github.com/gajus/eslint-plugin-flowtype/commit/a99721b)) # [2.22.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.21.0...v2.22.0) (2016-10-24) ### Features * ObjectTypeIndexer in spaceBeforeTypeColon & spaceAfterTypeColon ([82c87c4](https://github.com/gajus/eslint-plugin-flowtype/commit/82c87c4)), closes [#134](https://github.com/gajus/eslint-plugin-flowtype/issues/134) # [2.21.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.20.0...v2.21.0) (2016-10-22) ### Features * Add variance support to spaceBeforeTypeColon & spaceAfterTypeColon ([4a7f87f](https://github.com/gajus/eslint-plugin-flowtype/commit/4a7f87f)), closes [#137](https://github.com/gajus/eslint-plugin-flowtype/issues/137) # [2.20.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.19.0...v2.20.0) (2016-10-06) ### Features * add annotation enforcement option ([dd71ce8](https://github.com/gajus/eslint-plugin-flowtype/commit/dd71ce8)) # [2.19.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.18.2...v2.19.0) (2016-09-20) ### Bug Fixes * parens in TypeCastExpression ([0e0081f](https://github.com/gajus/eslint-plugin-flowtype/commit/0e0081f)) ### Features * add rule `sort-keys` (fixes #104) ([f6b8deb](https://github.com/gajus/eslint-plugin-flowtype/commit/f6b8deb)), closes [#104](https://github.com/gajus/eslint-plugin-flowtype/issues/104) * check TypeCastExpressions in type colon spacing rules ([98839f0](https://github.com/gajus/eslint-plugin-flowtype/commit/98839f0)) ## [2.18.2](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.18.1...v2.18.2) (2016-09-18) ## [2.18.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.18.0...v2.18.1) (2016-09-15) # [2.18.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.17.1...v2.18.0) (2016-09-15) ### Features * add rule `no-dupe-keys` (fixes #108) (#109) ([6a65de0](https://github.com/gajus/eslint-plugin-flowtype/commit/6a65de0)), closes [#108](https://github.com/gajus/eslint-plugin-flowtype/issues/108) [(#109](https://github.com/(/issues/109) ## [2.17.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.17.0...v2.17.1) (2016-09-12) ### Bug Fixes * config file (json failing lint) ([eedcac7](https://github.com/gajus/eslint-plugin-flowtype/commit/eedcac7)) * correct recommended config name ([35150d4](https://github.com/gajus/eslint-plugin-flowtype/commit/35150d4)) * disable lint for one run ([3745498](https://github.com/gajus/eslint-plugin-flowtype/commit/3745498)) # [2.17.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.16.1...v2.17.0) (2016-09-12) ### Features * define recommended configuration ([dc2e35b](https://github.com/gajus/eslint-plugin-flowtype/commit/dc2e35b)) * export recommended configuration ([f7d7a21](https://github.com/gajus/eslint-plugin-flowtype/commit/f7d7a21)) ## [2.16.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.16.0...v2.16.1) (2016-09-09) # [2.16.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.15.0...v2.16.0) (2016-09-07) ### Bug Fixes * `delimiter-dangle` with indexers ([9ff6f37](https://github.com/gajus/eslint-plugin-flowtype/commit/9ff6f37)) * reported locations in `delimiter-dangle` ([06fbd92](https://github.com/gajus/eslint-plugin-flowtype/commit/06fbd92)) ### Features * add `delimiter-dangle` for trailing commas/semicolons ([788f480](https://github.com/gajus/eslint-plugin-flowtype/commit/788f480)) # [2.15.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.14.3...v2.15.0) (2016-09-05) ### Features * options to prevent specific types in `no-weak-types` (#99) ([9c903ad](https://github.com/gajus/eslint-plugin-flowtype/commit/9c903ad)) ## [2.14.3](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.14.2...v2.14.3) (2016-09-05) ### Bug Fixes * ensure not to print private tokens ([1e41818](https://github.com/gajus/eslint-plugin-flowtype/commit/1e41818)) ## [2.14.2](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.14.1...v2.14.2) (2016-09-05) ### Bug Fixes * move tag check prior to branch check ([29b35d0](https://github.com/gajus/eslint-plugin-flowtype/commit/29b35d0)) ## [2.14.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.14.0...v2.14.1) (2016-09-05) ### Bug Fixes * add a condition to prevent empty commit ([2e6ddfa](https://github.com/gajus/eslint-plugin-flowtype/commit/2e6ddfa)) * fix release script ([260b86b](https://github.com/gajus/eslint-plugin-flowtype/commit/260b86b)) # [2.14.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.13.0...v2.14.0) (2016-09-05) ### Features * add new rule `no-weak-types` (#96) ([c1a94c5](https://github.com/gajus/eslint-plugin-flowtype/commit/c1a94c5)) # [2.13.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.12.1...v2.13.0) (2016-09-03) ### Features * add new rule `boolean-style` (#98) ([1ab7902](https://github.com/gajus/eslint-plugin-flowtype/commit/1ab7902)) ## [2.12.1](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.12.0...v2.12.1) (2016-09-01) ### Bug Fixes * allow uppercase sequences in 'type-id-match' (#93) ([000b0d1](https://github.com/gajus/eslint-plugin-flowtype/commit/000b0d1)) # [2.12.0](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.11.5...v2.12.0) (2016-09-01) ### Bug Fixes * add --no-verify to docs commit ([393643b](https://github.com/gajus/eslint-plugin-flowtype/commit/393643b)) * add --no-verify to standard-version ([22a0559](https://github.com/gajus/eslint-plugin-flowtype/commit/22a0559)) ### Features * add new rule "semi" for semicolon linting (#95) ([ead974d](https://github.com/gajus/eslint-plugin-flowtype/commit/ead974d)) ## [2.11.5](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.11.4...v2.11.5) (2016-09-01) ## [2.11.4](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.11.3...v2.11.4) (2016-08-23) ## [2.11.3](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.11.2...v2.11.3) (2016-08-23) ### Bug Fixes * commit documentation changes ([15a8289](https://github.com/gajus/eslint-plugin-flowtype/commit/15a8289)) ## [2.11.2](https://github.com/gajus/eslint-plugin-flowtype/compare/v2.11.1...v2.11.2) (2016-08-23) ### Bug Fixes * make release.sh executable ([6fa6f89](https://github.com/gajus/eslint-plugin-flowtype/commit/6fa6f89)) eslint-plugin-flowtype-2.25.0/CONTRIBUTING.md000066400000000000000000000030671300375303300204750ustar00rootroot00000000000000# Contributing **`README.md` is a generated file. Do not edit it directly.** Edit the files inside `.README` instead. ## Pre-Commit Hook When making a commit, the following Pre-Commit hooks run: * tests * lint * commit message validation (see "Commit Messages" below) ## Commit Messages All commit messages must begin with one of the following prefixes: * `fix: ` * `feat: ` * `refactor: ` * `docs: ` * `chore: ` The prefix is used to bump the correct segment of the version number automatically during deploy. ## Tests Run them with `npm t`. ## Lint Run with `npm run lint`. ## Adding a Rule ### Source & Tests 1. Create a file in `tests/rules/assertions` named the `camelCase` version of your rule name with the following template: * `export default { invalid: [], valid: [] }` 2. Add your test file to `tests/index.js` 3. Create a file in `src/rules` named the `camelCase` version of your rule name 4. Add your rule file to `src/index.js` ### Adding Documentation 1. Create new file in `./README/rules/[rule-name].md`. * Use [./.README/rules/require-valid-file-annotation.md](./.README/rules/require-valid-file-annotation.md) as a template. * Ensure that rule documentation document includes `` declaration. 1. Update [./.README/README.md](/.README/README.md) to include the new rule. A CI service will build and publish the new documentation. Note: The section "The following patterns are considered problems:" and "The following patterns are not considered problems:" is **generated automatically** using the test cases. eslint-plugin-flowtype-2.25.0/LICENSE000066400000000000000000000027711300375303300172520ustar00rootroot00000000000000Copyright (c) 2015, Gajus Kuizinas (http://gajus.com/) All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Gajus Kuizinas (http://gajus.com/) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANUARY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. eslint-plugin-flowtype-2.25.0/README.md000066400000000000000000002425111300375303300175220ustar00rootroot00000000000000 # eslint-plugin-flowtype [![NPM version](http://img.shields.io/npm/v/eslint-plugin-flowtype.svg?style=flat-square)](https://www.npmjs.org/package/eslint-plugin-flowtype) [![Travis build status](http://img.shields.io/travis/gajus/eslint-plugin-flowtype/master.svg?style=flat-square)](https://travis-ci.org/gajus/eslint-plugin-flowtype) [![js-canonical-style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](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) * [Settings](#eslint-plugin-flowtype-settings) * [`onlyFilesWithFlowAnnotation`](#eslint-plugin-flowtype-settings-onlyfileswithflowannotation) * [Rules](#eslint-plugin-flowtype-rules) * [`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) * [`generic-spacing`](#eslint-plugin-flowtype-rules-generic-spacing) * [`no-dupe-keys`](#eslint-plugin-flowtype-rules-no-dupe-keys) * [`no-weak-types`](#eslint-plugin-flowtype-rules-no-weak-types) * [`object-type-delimiter`](#eslint-plugin-flowtype-rules-object-type-delimiter) * [`require-parameter-type`](#eslint-plugin-flowtype-rules-require-parameter-type) * [`require-return-type`](#eslint-plugin-flowtype-rules-require-return-type) * [`require-valid-file-annotation`](#eslint-plugin-flowtype-rules-require-valid-file-annotation) * [`semi`](#eslint-plugin-flowtype-rules-semi) * [`sort-keys`](#eslint-plugin-flowtype-rules-sort-keys) * [`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) * [`type-id-match`](#eslint-plugin-flowtype-rules-type-id-match) * [`union-intersection-spacing`](#eslint-plugin-flowtype-rules-union-intersection-spacing) * [`use-flow-type`](#eslint-plugin-flowtype-rules-use-flow-type) * [`valid-syntax`](#eslint-plugin-flowtype-rules-valid-syntax) ## Installation 1. Install [ESLint](https://www.github.com/eslint/eslint). 1. Install [`babel-eslint`](https://github.com/babel/babel-eslint) parser (ESLint parser [does not support type annotations](https://github.com/eslint/eslint/issues/2157)). 1. Install [`eslint-plugin-flowtype`](https://github.com/gajus/eslint-plugin-flowtype) plugin. ```sh npm install eslint npm install babel-eslint npm install eslint-plugin-flowtype ``` ## Configuration 1. Set `parser` property to `babel-eslint`. 1. Add `plugins` section and specify `eslint-plugin-flowtype` as a plugin. 1. Enable rules. ```json { "parser": "babel-eslint", "plugins": [ "flowtype" ], "rules": { "flowtype/boolean-style": [ 2, "boolean" ], "flowtype/define-flow-type": 1, "flowtype/delimiter-dangle": [ 2, "never" ], "flowtype/generic-spacing": [ 2, "never" ], "flowtype/no-weak-types": 2, "flowtype/object-type-delimiter": [ 2, "comma" ], "flowtype/require-parameter-type": 2, "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 } } } ``` ### Shareable configurations #### 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. ## Settings ### onlyFilesWithFlowAnnotation 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 } } } ``` ## Rules ### 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 ``` ### define-flow-type 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 // Additional rules: {"no-undef":2} 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} interface AType {} // Additional rules: {"no-undef":2} ({ a: ({b() {}}: AType) }) // Additional rules: {"no-undef":2} type X = {Y(): BType} // Additional rules: {"no-undef":2} interface AType {} // 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 // 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"]} 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"]} interface AType {} // 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(): BType} // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} interface AType {} // Additional rules: {"no-undef":2,"no-use-before-define":[2,"nofunc"]} ``` ### delimiter-dangle _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent use of trailing commas in Object and Tuple annotations. This rule takes one argument which mirrors ESLint's default `comma-dangle` rule. 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 default value is `'never'`. 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: ["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 = [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"] 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 = [string, number] // Options: ["never"] type X = [string, number] // Options: ["never"] type X = [ string, number ] // Options: ["always"] type X = [string, number,] // Options: ["always"] type X = [ string, number, ] // Options: ["always-multiline"] type X = [ foo, string ] // Options: ["always-multiline"] type X = [ foo, string, ] // Options: ["only-multiline"] type X = [ number, string ] // Options: ["only-multiline"] type X = [ number, string ] // Options: ["only-multiline"] type X = [ number, string, ] // Options: ["never"] type X = [] // Options: ["always"] type X = [] // Options: ["always-multiline"] type X = [] // Options: ["only-multiline"] type X = [] ``` ### generic-spacing _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing within generic type annotation parameters. This rule takes one argument. If it is `'never'` then a problem is raised when there is a space surrounding the generic type parameters. If it is `'always'` then a problem is raised when there is no space surrounding the generic type parameters. The default value is `'never'`. The following patterns are considered problems: ```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 // 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 // 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 // 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 type X = Promise<(string)> 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))) > ``` ### 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": { "flowtype/no-dupe-keys": 2 } } ``` The following patterns are considered problems: ```js type FooType = { a: number, b: string, a: number } // Message: Duplicate property. type FooType = { a: number, b: string, a: string } // Message: Duplicate property. ``` The following patterns are not considered problems: ```js type FooType = { a: number, b: string, c: number } ``` ### no-weak-types Warns against weak type annotations *any*, *Object* and *Function*. These types can cause flow to silently skip over portions of your code, which would have otherwise caused type errors. This rule optionally takes one argument, an object to configure which type warnings to enable. By default, all of the warnings are enabled. e.g. to disable the `any` warning (allowing it to exist in your code), while continuing to warn about `Object` and `Function`: ```js { "rules": { "flowtype/no-weak-types": [2, { "any": false, "Object": true, "Function": true }] } } // or, the following is equivalent as default is true: { "rules": { "flowtype/no-weak-types": [2, { "any": false }] } } ``` The following patterns are considered problems: ```js function foo(thing): any {} // Message: Unexpected use of weak type "any" function foo(thing): Promise {} // Message: Unexpected use of weak type "any" function foo(thing): Promise> {} // Message: Unexpected use of weak type "any" function foo(thing): Object {} // Message: Unexpected use of weak type "Object" function foo(thing): Promise {} // Message: Unexpected use of weak type "Object" function foo(thing): Promise> {} // Message: Unexpected use of weak type "Object" function foo(thing): Function {} // Message: Unexpected use of weak type "Function" function foo(thing): Promise {} // Message: Unexpected use of weak type "Function" function foo(thing): Promise> {} // Message: Unexpected use of weak type "Function" (foo: any) => {} // Message: Unexpected use of weak type "any" (foo: Function) => {} // Message: Unexpected use of weak type "Function" (foo?: any) => {} // Message: Unexpected use of weak type "any" (foo?: Function) => {} // Message: Unexpected use of weak type "Function" (foo: { a: any }) => {} // Message: Unexpected use of weak type "any" (foo: { a: Object }) => {} // Message: Unexpected use of weak type "Object" (foo: any[]) => {} // Message: Unexpected use of weak type "any" type Foo = any // Message: Unexpected use of weak type "any" type Foo = Function // Message: Unexpected use of weak type "Function" type Foo = { a: any } // Message: Unexpected use of weak type "any" type Foo = { a: Object } // Message: Unexpected use of weak type "Object" type Foo = { (a: Object): string } // Message: Unexpected use of weak type "Object" type Foo = { (a: string): Function } // Message: Unexpected use of weak type "Function" function foo(thing: any) {} // Message: Unexpected use of weak type "any" function foo(thing: Object) {} // Message: Unexpected use of weak type "Object" var foo: Function // Message: Unexpected use of weak type "Function" var foo: Object // Message: Unexpected use of weak type "Object" class Foo { props: any } // Message: Unexpected use of weak type "any" class Foo { props: Object } // Message: Unexpected use of weak type "Object" var foo: any // Message: Unexpected use of weak type "any" // Options: [{"Function":false}] type X = any; type Y = Function; type Z = Object // Message: Unexpected use of weak type "any" // Message: Unexpected use of weak type "Object" // Options: [{"Object":false,"any":false}] type X = any; type Y = Function; type Z = Object // Message: Unexpected use of weak type "Function" ``` The following patterns are not considered problems: ```js function foo(thing): string {} function foo(thing): Promise {} function foo(thing): Promise> {} (foo?: string) => {} (foo: ?string) => {} (foo: { a: string }) => {} (foo: { a: ?string }) => {} (foo: string[]) => {} type Foo = string type Foo = { a: string } type Foo = { (a: string): string } function foo(thing: string) {} var foo: string class Foo { props: string } // Options: [{"Object":false,"any":false}] type X = any; type Y = Object // Options: [{"Function":false}] type X = Function ``` ### object-type-delimiter _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent separators between properties in Flow object types. This rule takes one argument. If it is `'comma'` then a problem is raised when using `;` as a separator. If it is `'semicolon'` then a problem is raised when using `,` as a separator. The default value is `'comma'`. _This rule is ported from `babel/flow-object-type`, however the default option was changed._ The following patterns are considered problems: ```js // Options: ["semicolon"] type Foo = { a: Foo, b: Bar } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] type Foo = { a: Foo; b: Bar } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] type Foo = { [a: string]: Foo, [b: string]: Bar } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] type Foo = { [a: string]: Foo; [b: string]: Bar } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] type Foo = { (): Foo, (): Bar } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] type Foo = { (): Foo; (): Bar } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] declare class Foo { a: Foo, } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] declare class Foo { a: Foo; } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] declare class Foo { [a: string]: Foo, } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] declare class Foo { a: Foo; } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] declare class Foo { (): Foo, } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] declare class Foo { (): Foo; } // Message: Prefer commas to semicolons in object and class types // Options: ["semicolon"] declare class Foo { static (): Foo, } // Message: Prefer semicolons to commas in object and class types // Options: ["comma"] declare class Foo { static (): Foo; } // Message: Prefer commas to semicolons in object and class types ``` The following patterns are not considered problems: ```js // Options: ["semicolon"] type Foo = { a: Foo; b: Bar } // Options: ["comma"] type Foo = { a: Foo, b: Bar } // Options: ["semicolon"] type Foo = { [a: string]: Foo; [b: string]: Bar } // Options: ["comma"] type Foo = { [a: string]: Foo, [b: string]: Bar } // Options: ["semicolon"] type Foo = { (): Foo; (): Bar } // Options: ["comma"] type Foo = { (): Foo, (): Bar } type Foo = { a: Foo, b: Bar } type Foo = { [a: string]: Foo, [b: string]: Bar } type Foo = { (): Foo, (): Bar } // Options: ["semicolon"] declare class Foo { a: Foo; } // Options: ["comma"] declare class Foo { a: Foo, } // Options: ["semicolon"] declare class Foo { [a: string]: Foo; } // Options: ["comma"] declare class Foo { [a: string]: Foo, } // Options: ["semicolon"] declare class Foo { (): Foo; } // Options: ["comma"] declare class Foo { (): Foo, } ``` ### require-parameter-type Requires that all function parameters have type annotations. #### Options You can skip all arrow functions by providing the `excludeArrowFunctions` option with `true`. Alternatively, you can want to exclude only concise arrow functions (e.g. `x => x * 2`). Provide `excludeArrowFunctions` with `expressionsOnly` for this. ```js { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeArrowFunctions": true } ] } } { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeArrowFunctions": "expressionsOnly" } ] } } ``` You can exclude parameters that match a certain regex by using `excludeParameterMatch`. ```js { "rules": { "flowtype/require-parameter-type": [ 2, { "excludeParameterMatch": "^_" } ] } } ``` This excludes all parameters that start with an underscore (`_`). The default pattern is `a^`, which doesn't match anything, i.e., all parameters are checked. The following patterns are considered problems: ```js (foo) => {} // Message: Missing "foo" parameter type annotation. function x(foo) {} // Message: Missing "foo" parameter type annotation. // Options: [{"excludeArrowFunctions":true}] function x(foo) {} // Message: Missing "foo" parameter type annotation. (foo = 'FOO') => {} // Message: Missing "foo" parameter type annotation. (...foo) => {} // Message: Missing "foo" parameter type annotation. ({foo}) => {} // Message: Missing "{foo}" parameter type annotation. ([foo]) => {} // Message: Missing "[foo]" parameter type annotation. ({foo = 1} = {}) => {} // Message: Missing "{foo = 1}" parameter type annotation. // @flow (foo) => {} // Message: Missing "foo" parameter type annotation. // Options: [{"excludeArrowFunctions":"expressionsOnly"}] (foo) => {} // Message: Missing "foo" parameter type annotation. // Options: [{"excludeArrowFunctions":"expressionsOnly"}] function x(foo) {} // Message: Missing "foo" parameter type annotation. // Options: [{"excludeParameterMatch":"^_"}] (_foo: number, bar) => {} // Message: Missing "bar" parameter type annotation. // Options: [{"excludeParameterMatch":"^_"}] (_foo, bar) => {} // Message: Missing "bar" parameter type annotation. ``` The following patterns are not considered problems: ```js (foo: string) => {} (foo: string = 'FOO') => {} (...foo: string) => {} ({foo}: {foo: string}) => {} ([foo]: Array) => {} (foo) => {} // Options: [{"excludeArrowFunctions":true}] (foo) => {} // Options: [{"excludeArrowFunctions":"expressionsOnly"}] (foo) => 3 // Options: [{"excludeParameterMatch":"^_"}] (_foo, bar: string) => {} // Options: [{"excludeParameterMatch":"^_"}] (_foo: number, bar: string) => {} ``` ### require-return-type Requires that functions have return type annotation. #### Options You can skip all arrow functions by providing the `excludeArrowFunctions` option with `true`. Alternatively, you can want to exclude only concise arrow function (e.g. `() => 2`). Provide `excludeArrowFunctions` with `expressionsOnly` for this. ```js { "rules": { "flowtype/require-return-type": [ 2, "always", { "excludeArrowFunctions": true } ] } } { "rules": { "flowtype/require-return-type": [ 2, "always", { "excludeArrowFunctions": "expressionsOnly" } ] } } ``` The following patterns are considered problems: ```js (foo) => { return "foo"; } // Message: Missing return type annotation. // Options: ["always"] (foo) => { return "foo"; } // Message: Missing return type annotation. // Options: ["always"] (foo) => "foo" // Message: Missing return type annotation. (foo) => ({}) // Message: Missing return type annotation. (foo): undefined => { return; } // Message: Must not annotate undefined return type. (foo): void => { return; } // Message: Must not annotate undefined return type. (foo): undefined => { return undefined; } // Message: Must not annotate undefined return type. (foo): void => { return void 0; } // Message: Must not annotate undefined return type. // Options: ["always",{"annotateUndefined":"never"}] (foo): undefined => { return; } // Message: Must not annotate undefined return type. // Options: ["always",{"annotateUndefined":"never"}] (foo): void => { return; } // Message: Must not annotate undefined return type. // Options: ["always",{"annotateUndefined":"always"}] (foo) => { return; } // Message: Must annotate undefined return type. // Options: ["always",{"annotateUndefined":"never"}] (foo): undefined => { return undefined; } // Message: Must not annotate undefined return type. // Options: ["always",{"annotateUndefined":"always"}] (foo) => { return undefined; } // Message: Must annotate undefined return type. // Options: ["always",{"annotateUndefined":"always"}] (foo) => { return void 0; } // Message: Must annotate undefined return type. // @flow (foo) => { return 1; } // Message: Missing return type annotation. // Options: ["always",{"annotateUndefined":"always"}] // @flow (foo) => { return undefined; } // Message: Must annotate undefined return type. // Options: ["always"] async () => { return 2; } // Message: Missing return type annotation. // Options: ["always",{"annotateUndefined":"always"}] async () => {} // Message: Missing return type annotation. // Options: ["always",{"annotateUndefined":"always"}] async function x() {} // Message: Missing return type annotation. // Options: ["always"] async () => { return; } // Message: Missing return type annotation. // Options: ["always"] function* x() {} // Message: Missing return type annotation. // Options: ["always",{"excludeArrowFunctions":"expressionsOnly"}] () => { return 3; } // Message: Missing return type annotation. // Options: ["always",{"excludeArrowFunctions":"expressionsOnly"}] async () => { return 4; } // Message: Missing return type annotation. ``` The following patterns are not considered problems: ```js (foo): string => {} // Options: ["always"] (foo): string => {} (foo) => { return; } (foo): Object => ( {} ) (foo) => { return undefined; } (foo) => { return void 0; } // Options: ["always",{"annotateUndefined":"always"}] (foo): undefined => { return; } // Options: ["always",{"annotateUndefined":"always"}] (foo): void => { return; } // Options: ["always",{"annotateUndefined":"never"}] (foo) => { return; } // Options: ["always",{"annotateUndefined":"never"}] (foo) => { return undefined; } // Options: ["always",{"annotateUndefined":"never"}] (foo) => { return void 0; } // Options: ["always",{"annotateUndefined":"always"}] (foo): undefined => { return undefined; } // Options: ["always",{"annotateUndefined":"always"}] (foo): void => { return void 0; } // Options: ["always"] (foo) => { return 1; } // Options: ["always",{"annotateUndefined":"always"}] (foo) => { return undefined; } // Options: ["always",{"annotateUndefined":"always"}] async function doThing(): Promise {} // Options: ["always",{"annotateUndefined":"always"}] function* doThing(): Generator { yield 2; } async (foo): Promise => { return 3; } // Options: ["always",{"excludeArrowFunctions":true}] () => 3 // Options: ["always",{"excludeArrowFunctions":true}] () => { return 4; } // Options: ["always",{"excludeArrowFunctions":true}] () => undefined // Options: ["always",{"annotateUndefined":"always","excludeArrowFunctions":true}] () => undefined // Options: ["always",{"annotateUndefined":"always","excludeArrowFunctions":true}] () => { return undefined; } // Options: ["always",{"excludeArrowFunctions":"expressionsOnly"}] () => 3 // Options: ["always",{"excludeArrowFunctions":"expressionsOnly"}] async () => 3 ``` ### require-valid-file-annotation This rule validates Flow file annotations. This rule can optionally report missing or missed placed annotations, common typos (e.g. `// @floww`), and enforce a consistant annotation style. #### Options The rule has a string option: * `"never"` (default): Never report files that are missing an `@flow` annotation. * `"always"`: Always report files that are missing an `@flow` annotation This rule has an object option: * `"annotationStyle"` - Enforce a consistant file annotation style. * `"none"` (default): Either annotation style is accepted. * `"line"`: Require single line annotations (i.e. `// @flow`). * `"block"`: Require block annotations (i.e. `/* @flow */`). ```js { "rules": { "flowtype/require-valid-file-annotation": [ 2, "always" ] } } { "rules": { "flowtype/require-valid-file-annotation": [ 2, "always", { "annotationStyle": "block" } ] } } ``` The following patterns are considered problems: ```js ;// @flow // Message: Flow file annotation not at the top of the file. ; // @flow // Message: Flow file annotation not at the top of the file. // @Flow // Message: Malformed flow file annotation. // @floweeeeeee // Message: Malformed flow file annotation. // @NoFlow // Message: Malformed flow file annotation. // @nofloweeeeeee // Message: Malformed flow file annotation. // Options: ["always"] a; // Message: Flow file annotation is missing. // Options: ["always",{"annotationStyle":"line"}] /* @flow */ // Message: Flow file annotation style must be `// @flow` // Options: ["always",{"annotationStyle":"block"}] // @flow // Message: Flow file annotation style must be `/* @flow */` ``` The following patterns are not considered problems: ```js a; // @flow a; //@flow a; //**@flow a; /* foo @flow bar */ a; // @flow a; // @flow // @FLow // @noflow a; // Options: ["always"] a; // Options: ["always",{"annotationStyle":"line"}] // @flow // Options: ["always",{"annotationStyle":"block"}] /* @flow */ ``` ### semi _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent use of semicolons after type aliases. This rule takes one argument. If it is `'never'` then a problem is raised when there is a semicolon after a type alias. If it is `'always'` then a problem is raised when there is no semicolon after a type alias. The default value is `'always'`. The following patterns are considered problems: ```js // Options: [] type FooType = {} // Message: Missing semicolon. // Options: ["always"] type FooType = {} // Message: Missing semicolon. // Options: ["never"] type FooType = {}; // Message: Extra semicolon. ``` The following patterns are not considered problems: ```js type FooType = {}; // Options: ["always"] type FooType = {}; // Options: ["always"] type FooType = { a: number; b: string; }; // Options: ["never"] type FooType = { a: number; b: string; } // Options: ["never"] type FooType = {} ``` ### sort-keys Enforces sorting of Object annotations. This rule mirrors ESlint's [sort-keys](http://eslint.org/docs/rules/sort-keys) rule. #### Options The first option specifies sort order. * `"asc"` (default) - enforce ascending sort order. * `"desc"` - enforce descending sort order. The second option takes an object with two possible properties. * `caseSensitive` - if `true`, enforce case-sensitive sort order. Default is `true`. * `natural` - if `true`, enforce [natural sort order](https://en.wikipedia.org/wiki/Natural_sort_order). Default is `false`. ```js { "rules": { "flowtype/sort-keys": [ 2, "asc", { "caseSensitive": true, "natural": false } ] } } ``` The following patterns are considered problems: ```js type FooType = { a: number, c: number, b: string } // Message: Expected type annotations to be in ascending order. "b" should be before "c". type FooType = { a: number, b: number, C: number } // Message: Expected type annotations to be in ascending order. "C" should be before "b". type FooType = { 1: number, 2: number, 10: number } // Message: Expected type annotations to be in ascending order. "10" should be before "2". // Options: ["desc"] type FooType = { a: number, b: number } // Message: Expected type annotations to be in descending order. "b" should be before "a". // Options: ["desc"] type FooType = { C: number, b: number, a: string } // Message: Expected type annotations to be in descending order. "b" should be before "C". // Options: ["desc"] type FooType = { 10: number, 2: number, 1: number } // Message: Expected type annotations to be in descending order. "2" should be before "10". // Options: ["asc",{"caseSensitive":false}] type FooType = { a: number, c: number, C: number, b: string } // Message: Expected type annotations to be in insensitive ascending order. "b" should be before "C". // Options: ["asc",{"caseSensitive":false}] type FooType = { a: number, C: number, c: number, b: string } // Message: Expected type annotations to be in insensitive ascending order. "b" should be before "c". // Options: ["asc",{"natural":true}] type FooType = { 1: number, 10: number, 2: boolean } // Message: Expected type annotations to be in natural ascending order. "2" should be before "10". ``` The following patterns are not considered problems: ```js type FooType = { a: number } type FooType = { a: number, b: number, c: (boolean | number) } type FooType = { C: number, a: string, b: foo } type FooType = { 1: number, 10: number, 2: boolean } // Options: ["desc"] type FooType = { c: number, b: number, a: number } // Options: ["desc"] type FooType = { b: string, a: {}, C: number } // Options: ["desc"] type FooType = { 2: number, 10: number, 1: boolean } // Options: ["asc",{"caseSensitive":false}] type FooType = { a: number, b: number, c: number, C: number } // Options: ["asc",{"caseSensitive":false}] type FooType = { a: number, b: number, C: number, c: number } // Options: ["asc",{"natural":true}] type FooType = { 1:number, 2: number, 10: number } ``` ### space-after-type-colon _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing after the type annotation colon. This rule takes one argument. If it is `'always'` then a problem is raised when there is no space after the type annotation colon. If it is `'never'` then a problem is raised when there is a space after the type annotation colon. The default value is `'always'`. The following patterns are considered problems: ```js // Options: ["never"] (foo: string) => {} // Message: There must be no space after "foo" parameter type annotation colon. // Options: ["always"] (foo: string) => {} // Message: There must be 1 space after "foo" parameter type annotation colon. // Options: ["always"] (foo:(() => void)) => {} // Message: There must be a space after "foo" parameter type annotation colon. // Options: ["never"] (foo: (() => void)) => {} // Message: There must be no space after "foo" parameter type annotation colon. // Options: ["always"] (foo: (() => void)) => {} // Message: There must be 1 space after "foo" parameter type annotation colon. ({ lorem, ipsum, dolor } : SomeType) => {} // Message: There must be 1 space after "{ lorem, ipsum, dolor }" parameter type annotation colon. (foo:{ a: string, b: number }) => {} // Message: There must be a space after "foo" parameter type annotation colon. ({ a, b } :{ a: string, b: number }) => {} // Message: There must be a space after "{ a, b }" parameter type annotation colon. ([ a, b ] :string[]) => {} // Message: There must be a space after "[ a, b ]" parameter type annotation colon. (i?:number) => {} // Message: There must be a space after "i" parameter type annotation colon. (i?: number) => {} // Message: There must be 1 space after "i" parameter type annotation colon. // Options: ["never"] (i?: number) => {} // Message: There must be no space after "i" parameter type annotation colon. // Options: ["always"] ():Object => {} // Message: There must be a space after return type colon. // Options: ["never"] (): Object => {} // Message: There must be no space after return type colon. // Options: ["always"] (): Object => {} // Message: There must be 1 space after return type colon. // Options: ["always"] ():(() => void) => {} // Message: There must be a space after return type colon. // Options: ["never"] (): (() => void) => {} // Message: There must be no space after return type colon. // Options: ["always"] (): (() => void) => {} // Message: There must be 1 space after return type colon. // Options: ["never"] export default function (foo: string) {} // Message: There must be no space after "foo" parameter type annotation colon. // Options: ["never"] function foo (foo: string) {} // Message: There must be no space after "foo" parameter type annotation colon. // Options: ["always"] (foo:string) => {} // Message: There must be a space after "foo" parameter type annotation colon. function foo (foo:string) {} // Message: There must be a space after "foo" parameter type annotation colon. async function foo({ lorem, ipsum, dolor }:SomeType) {} // Message: There must be a space after "{ lorem, ipsum, dolor }" parameter type annotation colon. function x(i?:number) {} // Message: There must be a space after "i" parameter type annotation colon. function x(i?: number) {} // Message: There must be 1 space after "i" parameter type annotation colon. // Options: ["never"] function x(i?: number) {} // Message: There must be no space after "i" parameter type annotation colon. function a():x {} // Message: There must be a space after return type colon. // Options: ["always"] function a(): x {} // Message: There must be 1 space after return type colon. // Options: ["never"] function a(): x {} // Message: There must be no space after return type colon. type X = (foo:number) => string // Message: There must be a space after "foo" parameter type annotation colon. // Options: ["never"] type X = (foo: number) => string // Message: There must be no space after "foo" parameter type annotation colon. type X = (foo: number) => string // Message: There must be 1 space after "foo" parameter type annotation colon. type X = (foo:?number) => string // Message: There must be a space after "foo" parameter type annotation colon. type X = (foo:(number)) => string // Message: There must be a space after "foo" parameter type annotation colon. type X = (foo:((number))) => string // Message: There must be a space after "foo" parameter type annotation colon. type X = (foo: ((number))) => string // Message: There must be 1 space after "foo" parameter type annotation colon. // Options: ["never"] type X = (foo: ((number))) => string // Message: There must be no space after "foo" parameter type annotation colon. type X = (foo:?(number)) => string // Message: There must be a space after "foo" parameter type annotation colon. type TArrayPredicate = (el: T, i?:number) => boolean // Message: There must be a space after "i" parameter type annotation colon. type TArrayPredicate = (el: T, i?: number) => boolean // Message: There must be 1 space after "i" parameter type annotation colon. // Options: ["never"] type TArrayPredicate = (el:T, i?: number) => boolean // Message: There must be no space after "i" parameter type annotation colon. class X { foo:string } // Message: There must be a space after "foo" class property type annotation colon. // Options: ["never"] class X { foo: string } // Message: There must be no space after "foo" class property type annotation colon. class X { foo:?string } // Message: There must be a space after "foo" class property type annotation colon. // Options: ["never"] class X { foo: ?string } // Message: There must be no space after "foo" class property type annotation colon. class X { static foo:number } // Message: There must be a space after "foo" class property type annotation colon. // Options: ["never"] class X { static foo: number } // Message: There must be no space after "foo" class property type annotation colon. class X { static foo :number } // Message: There must be a space after "foo" class property type annotation colon. // Options: ["never"] class X { static foo : number } // Message: There must be no space after "foo" class property type annotation colon. declare class X { static foo:number } // Message: There must be a space after "foo" type annotation colon. // Options: ["never"] declare class X { static foo: number } // Message: There must be no space after "foo" type annotation colon. declare class X { static foo :number } // Message: There must be a space after "foo" type annotation colon. // Options: ["never"] declare class X { static foo : number } // Message: There must be no space after "foo" type annotation colon. class X { +foo:string } // Message: There must be a space after "foo" class property type annotation colon. class X { +foo: string } // Message: There must be 1 space after "foo" class property type annotation colon. // Options: ["never"] class X { +foo: string } // Message: There must be no space after "foo" class property type annotation colon. class X { static +foo:string } // Message: There must be a space after "foo" class property type annotation colon. class X { static +foo: string } // Message: There must be 1 space after "foo" class property type annotation colon. // Options: ["never"] class X { static +foo: string } // Message: There must be no space after "foo" class property type annotation colon. type X = { foo:string } // Message: There must be a space after "foo" type annotation colon. // Options: ["always"] type X = { foo:string } // Message: There must be a space after "foo" type annotation colon. // Options: ["never"] type X = { foo: string } // Message: There must be no space after "foo" type annotation colon. type X = { foo: string } // Message: There must be 1 space after "foo" type annotation colon. type X = { foo?:string } // Message: There must be a space after "foo" type annotation colon. // Options: ["never"] type X = { foo?: string } // Message: There must be no space after "foo" type annotation colon. type X = { foo?:?string } // Message: There must be a space after "foo" type annotation colon. type X = { foo?: ?string } // Message: There must be 1 space after "foo" type annotation colon. type Foo = { barType:(string | () => void) } // Message: There must be a space after "barType" type annotation colon. type Foo = { barType:(((string | () => void))) } // Message: There must be a space after "barType" type annotation colon. // Options: ["never"] type Foo = { barType: (string | () => void) } // Message: There must be no space after "barType" type annotation colon. type Foo = { barType: (string | () => void) } // Message: There must be 1 space after "barType" type annotation colon. type Foo = { barType: ((string | () => void)) } // Message: There must be 1 space after "barType" type annotation colon. type X = { get:() => A; } // Message: There must be a space after "get" type annotation colon. type X = { get:() => A; } // Message: There must be a space after "get" type annotation colon. // Options: ["never"] type X = { get: () => A; } // Message: There must be no space after "get" type annotation colon. // Options: ["never"] type X = { get: () => A; } // Message: There must be no space after "get" type annotation colon. type X = { get: () => A; } // Message: There must be 1 space after "get" type annotation colon. type X = { get: () => A; } // Message: There must be 1 space after "get" type annotation colon. type X = { +foo:string } // Message: There must be a space after "foo" type annotation colon. type X = { +foo: string } // Message: There must be 1 space after "foo" type annotation colon. // Options: ["never"] type X = { +foo: string } // Message: There must be no space after "foo" type annotation colon. type X = { +foo?:string } // Message: There must be a space after "foo" type annotation colon. type X = { +foo?: string } // Message: There must be 1 space after "foo" type annotation colon. // Options: ["never"] type X = { +foo?: string } // Message: There must be no space after "foo" type annotation colon. // Options: ["always"] type X = { [a:b]: c } // Message: There must be a space after type annotation colon. // Options: ["never"] type X = { [a: b]:c } // Message: There must be no space after type annotation colon. // Options: ["always"] type X = { [a: b]: c } // Message: There must be 1 space after type annotation colon. // Options: ["always"] type X = { +[a:b]: c } // Message: There must be a space after type annotation colon. // Options: ["never"] type X = { +[a: b]:c } // Message: There must be no space after type annotation colon. // Options: ["always"] type X = { +[a: b]: c } // Message: There must be 1 space after type annotation colon. // Options: ["always"] type X = { [a: b]:c } // Message: There must be a space after type annotation colon. // Options: ["never"] type X = { [a:b]: c } // Message: There must be no space after type annotation colon. // Options: ["always"] type X = { [a: b]: c } // Message: There must be 1 space after type annotation colon. // Options: ["always"] type X = { [a:b]:c } // Message: There must be a space after type annotation colon. // Message: There must be a space after type annotation colon. // Options: ["never"] type X = { [a: b]: c } // Message: There must be no space after type annotation colon. // Message: There must be no space after type annotation colon. // Options: ["always"] type X = { [a: b]: c } // Message: There must be 1 space after type annotation colon. // Message: There must be 1 space after type annotation colon. // Options: ["always"] type X = { [a:(b)]:(c) } // Message: There must be a space after type annotation colon. // Message: There must be a space after type annotation colon. // Options: ["never"] type X = { [a: (b)]: (c) } // Message: There must be no space after type annotation colon. // Message: There must be no space after type annotation colon. // Options: ["never"] const x = ({}: {}) // Message: There must be no space after type cast colon. // Options: ["always"] const x = ({}:{}) // Message: There must be a space after type cast colon. // Options: ["always"] const x = ({}: {}) // Message: There must be 1 space after type cast colon. // Options: ["never"] ((x): (string)) // Message: There must be no space after type cast colon. // Options: ["always"] ((x):(string)) // Message: There must be a space after type cast colon. // Options: ["always"] ((x): (string)) // Message: There must be 1 space after type cast colon. ``` The following patterns are not considered problems: ```js (foo) => {} (foo: string) => {} (foo: (string|number)) => {} // Options: ["never"] (foo:string) => {} // Options: ["always"] (foo: string) => {} // Options: ["never"] (foo:(() => void)) => {} // Options: ["always"] (foo: (() => void)) => {} ({ lorem, ipsum, dolor }: SomeType) => {} (foo: { a: string, b: number }) => {} ({ a, b }: ?{ a: string, b: number }) => {} ([ a, b ]: string[]) => {} (i?: number) => {} // Options: ["never"] (i?:number) => {} // Options: ["never"] ():Object => {} // Options: ["always"] (): Object => {} // Options: ["never"] ():(number | string) => {} // Options: ["always"] (): (number | string) => {} // Options: ["never"] ():number|string => {} // Options: ["always"] (): number|string => {} // Options: ["never"] ():(() => void) => {} // Options: ["always"] (): (() => void) => {} // Options: ["never"] ():( () => void ) => {} // Options: ["always"] (): ( () => void ) => {} (): { a: number, b: string } => {} // Options: ["never"] () :{ a:number, b:string } => {} function x(foo: string) {} class Foo { constructor(foo: string) {} } // Options: ["never"] function x(foo:string) {} // Options: ["never"] class Foo { constructor(foo:string) {} } async function foo({ lorem, ipsum, dolor }: SomeType) {} function x({ a, b }: { a: string, b: number }) {} function x(i?: number) {} // Options: ["never"] function x(i?:number) {} function a(): x {} // Options: ["never"] function a():x {} function a(): (number | string) {} // Options: ["never"] function a() :(number | string) {} type X = (foo: number) => string; type X = (foo : number) => string; type X = (foo: ?number) => string; type X = (foo? : ?number) => string; type X = (foo: ?{ x: number }) => string; // Options: ["never"] type X = (foo:number) => string; // Options: ["never"] type X = (foo:?{ x:number }) => string; type X = (foo: (number)) => string type X = (foo: ((number))) => string // Options: ["never"] type X = (foo:((number))) => string type X = ?(foo: ((number))) => string // Options: ["never"] type X = ?(foo:((number))) => string type TArrayPredicate = (el: T, i?: number) => boolean // Options: ["never"] type TArrayPredicate = (el:T, i?:number) => boolean class Foo { bar } class Foo { bar = 3 } class Foo { bar: string } class Foo { bar: ?string } // Options: ["never"] class Foo { bar:string } // Options: ["never"] class Foo { bar:?string } class X { static foo : number } // Options: ["never"] class X { static foo :number } declare class X { static foo : number } // Options: ["never"] declare class X { static foo :number } class X { +foo: string } class X { static +foo: string } // Options: ["never"] class X { +foo:string } // Options: ["never"] class X { static +foo:string } type X = { foo: string } // Options: ["never"] type X = { foo:string } type X = { foo?: string } type X = { foo?: ?string } // Options: ["never"] type X = { foo?:?string } type Foo = { barType: (string | () => void) } type Foo = { barType: ((string | () => void)) } // Options: ["never"] type Foo = { barType:(string | () => void) } // Options: ["never"] type Foo = { barType:((string | () => void)) } type X = { get(): A; } type X = { get(): A; } // Options: ["never"] type X = { get(): A; } // Options: ["never"] type X = { get(): A; } type X = { get: () => A; } type X = { get: () => A; } // Options: ["never"] type X = { get:() => A; } // Options: ["never"] type X = { get:() => A; } type X = { +foo: string } type X = { +foo?: string } // Options: ["never"] type X = { +foo:string } // Options: ["never"] type X = { +foo?:string } // Options: ["always"] type X = { [a: b]: c } // Options: ["never"] type X = { [a:b]:c } // Options: ["always"] type X = { +[a: b]: c } // Options: ["never"] type X = { +[a:b]:c } // Options: ["never"] const x = ({}:{}) // Options: ["always"] const x = ({}: {}) // Options: ["never"] ((x):(string)) // Options: ["always"] ((x): (string)) ``` ### space-before-generic-bracket _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing before the opening `<` of generic type annotation parameters. This rule takes one argument. If it is `'never'` then a problem is raised when there is a space before the `<`. If it is `'always'` then a problem is raised when there is no space before the `<`. The default value is `'never'`. The following patterns are considered problems: ```js type X = Promise // Message: There must be no space before "Promise" generic type annotation bracket // Options: ["never"] type X = Promise // Message: There must be no space before "Promise" generic type annotation bracket type X = Promise // Message: There must be no space before "Promise" generic type annotation bracket // Options: ["always"] type X = Promise // Message: There must be a space before "Promise" generic type annotation bracket // Options: ["always"] type X = Promise // Message: There must be one space before "Promise" generic type annotation bracket ``` The following patterns are not considered problems: ```js type X = Promise // Options: ["always"] type X = Promise ``` ### space-before-type-colon _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing before the type annotation colon. This rule takes one argument. If it is `'always'` then a problem is raised when there is no space before the type annotation colon. If it is `'never'` then a problem is raised when there is a space before the type annotation colon. The default value is `'never'`. The following patterns are considered problems: ```js // Options: ["never"] (foo : string) => {} // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["never"] (foo ? : string) => {} // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] (foo: string) => {} // Message: There must be a space before "foo" parameter type annotation colon. // Options: ["always"] (foo : string) => {} // Message: There must be 1 space before "foo" parameter type annotation colon. // Options: ["always"] (foo?: string) => {} // Message: There must be a space before "foo" parameter type annotation colon. // Options: ["always"] (foo ? : string) => {} // Message: There must be 1 space before "foo" parameter type annotation colon. // Options: ["always"] (foo ?: string) => {} // Message: There must be a space before "foo" parameter type annotation colon. ({ lorem, ipsum, dolor } : SomeType) => {} // Message: There must be no space before "{ lorem, ipsum, dolor }" parameter type annotation colon. (foo : { a: string, b: number }) => {} // Message: There must be no space before "foo" parameter type annotation colon. ({ a, b } : { a: string, b: number }) => {} // Message: There must be no space before "{ a, b }" parameter type annotation colon. ([ a, b ] : string[]) => {} // Message: There must be no space before "[ a, b ]" parameter type annotation colon. () : x => {} // Message: There must be no space before return type colon. // Options: ["always"] (): x => {} // Message: There must be a space before return type colon. // Options: ["always"] () : x => {} // Message: There must be 1 space before return type colon. function x(foo : string) {} // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] function x(foo: string) {} // Message: There must be a space before "foo" parameter type annotation colon. var x = function (foo : string) {} // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] var x = function (foo: string) {} // Message: There must be a space before "foo" parameter type annotation colon. class Foo { constructor(foo : string ) {} } // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] class Foo { constructor(foo: string ) {} } // Message: There must be a space before "foo" parameter type annotation colon. async function foo({ lorem, ipsum, dolor } : SomeType) {} // Message: There must be no space before "{ lorem, ipsum, dolor }" parameter type annotation colon. function a() : x {} // Message: There must be no space before return type colon. // Options: ["always"] function a(): x {} // Message: There must be a space before return type colon. // Options: ["always"] function a() : x {} // Message: There must be 1 space before return type colon. type X = (foo :string) => string; // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] type X = (foo:string) => string; // Message: There must be a space before "foo" parameter type annotation colon. // Options: ["always"] type X = (foo :string) => string; // Message: There must be 1 space before "foo" parameter type annotation colon. type X = (foo? :string) => string; // Message: There must be no space before "foo" parameter type annotation colon. type X = (foo? :string) => string; // Message: There must be no space before "foo" parameter type annotation colon. // Options: ["always"] type X = (foo?:string) => string; // Message: There must be a space before "foo" parameter type annotation colon. type X = (foo? :?string) => string; // Message: There must be no space before "foo" parameter type annotation colon. class X { foo :string } // Message: There must be no space before "foo" class property type annotation colon. // Options: ["always"] class X { foo: string } // Message: There must be a space before "foo" class property type annotation colon. class X { foo :?string } // Message: There must be no space before "foo" class property type annotation colon. // Options: ["always"] class X { foo: ?string } // Message: There must be a space before "foo" class property type annotation colon. class X { static foo : number } // Message: There must be no space before "foo" class property type annotation colon. class X { static foo :number } // Message: There must be no space before "foo" class property type annotation colon. // Options: ["always"] class X { static foo: number } // Message: There must be a space before "foo" class property type annotation colon. // Options: ["always"] class X { static foo:number } // Message: There must be a space before "foo" class property type annotation colon. declare class Foo { static bar :number; } // Message: There must be no space before "bar" type annotation colon. declare class Foo { static bar : number; } // Message: There must be no space before "bar" type annotation colon. // Options: ["always"] declare class Foo { static bar:number; } // Message: There must be a space before "bar" type annotation colon. // Options: ["always"] declare class Foo { static bar: number; } // Message: There must be a space before "bar" type annotation colon. // Options: ["always"] class X { +foo: string } // Message: There must be a space before "foo" class property type annotation colon. // Options: ["always"] class X { +foo : string } // Message: There must be 1 space before "foo" class property type annotation colon. // Options: ["never"] class X { +foo : string } // Message: There must be no space before "foo" class property type annotation colon. // Options: ["always"] class X { static +foo: string } // Message: There must be a space before "foo" class property type annotation colon. // Options: ["always"] class X { static +foo : string } // Message: There must be 1 space before "foo" class property type annotation colon. // Options: ["never"] class X { static +foo : string } // Message: There must be no space before "foo" class property type annotation colon. type X = { foo : string } // Message: There must be no space before "foo" type annotation colon. // Options: ["never"] type X = { foo : string } // Message: There must be no space before "foo" type annotation colon. // Options: ["always"] type X = { foo: string } // Message: There must be a space before "foo" type annotation colon. // Options: ["always"] type X = { foo : string } // Message: There must be 1 space before "foo" type annotation colon. type X = { foo? : string } // Message: There must be no space before "foo" type annotation colon. // Options: ["always"] type X = { foo?: string } // Message: There must be a space before "foo" type annotation colon. // Options: ["always"] type X = { foo? : string } // Message: There must be 1 space before "foo" type annotation colon. // Options: ["always"] type X = { foo ?: string } // Message: There must be a space before "foo" type annotation colon. // Options: ["always"] type X = { +foo: string } // Message: There must be a space before "foo" type annotation colon. // Options: ["always"] type X = { +foo : string } // Message: There must be 1 space before "foo" type annotation colon. // Options: ["never"] type X = { +foo : string } // Message: There must be no space before "foo" type annotation colon. // Options: ["always"] type X = { +foo?: string } // Message: There must be a space before "foo" type annotation colon. // Options: ["always"] type X = { +foo? : string } // Message: There must be 1 space before "foo" type annotation colon. // Options: ["never"] type X = { +foo? : string } // Message: There must be no space before "foo" type annotation colon. // Options: ["always"] type X = { [a: b] : c } // Message: There must be a space before type annotation colon. // Options: ["never"] type X = { [a : b]: c } // Message: There must be no space before type annotation colon. // Options: ["always"] type X = { [a : b] : c } // Message: There must be 1 space before type annotation colon. // Options: ["always"] type X = { +[a:b] : c } // Message: There must be a space before type annotation colon. // Options: ["never"] type X = { +[a : b]: c } // Message: There must be no space before type annotation colon. // Options: ["always"] type X = { +[a : b] : c } // Message: There must be 1 space before type annotation colon. // Options: ["always"] type X = { [a : b]: c } // Message: There must be a space before type annotation colon. // Options: ["never"] type X = { [a: b] : c } // Message: There must be no space before type annotation colon. // Options: ["always"] type X = { [a : b] : c } // Message: There must be 1 space before type annotation colon. // Options: ["always"] type X = { [a:b]:c } // Message: There must be a space before type annotation colon. // Message: There must be a space before type annotation colon. // Options: ["never"] type X = { [a : b] : c } // Message: There must be no space before type annotation colon. // Message: There must be no space before type annotation colon. // Options: ["always"] type X = { [a : b] : c } // Message: There must be 1 space before type annotation colon. // Message: There must be 1 space before type annotation colon. // Options: ["always"] type X = { [a:(b)]:(c) } // Message: There must be a space before type annotation colon. // Message: There must be a space before type annotation colon. // Options: ["never"] type X = { [a : (b)] : (c) } // Message: There must be no space before type annotation colon. // Message: There must be no space before type annotation colon. // Options: ["never"] const x = ({} :{}) // Message: There must be no space before type cast colon. // Options: ["always"] const x = ({}:{}) // Message: There must be a space before type cast colon. // Options: ["always"] const x = ({} :{}) // Message: There must be 1 space before type cast colon. // Options: ["never"] ((x) : string) // Message: There must be no space before type cast colon. // Options: ["always"] ((x): string) // Message: There must be a space before type cast colon. // Options: ["always"] ((x) : string) // Message: There must be 1 space before type cast colon. ``` The following patterns are not considered problems: ```js (foo) => {} (foo: string) => {} (foo?: string) => {} (foo ?: string) => {} // Options: ["never"] (foo: string) => {} // Options: ["always"] (foo : string) => {} // Options: ["always"] (foo? : string) => {} // Options: ["always"] (foo ? : string) => {} // Options: ["always"] (foo ? : string) => {} ({ lorem, ipsum, dolor }: SomeType) => {} (foo: { a: string, b: number }) => {} ({ a, b }: ?{ a: string, b: number }) => {} (): { a: number, b: string } => {} // Options: ["always"] () : { a : number, b : string } => {} ([ a, b ]: string[]) => {} (): x => {} // Options: ["always"] () : x => {} (): (number | string) => {} // Options: ["always"] () : (number | string) => {} function x(foo: string) {} // Options: ["always"] function x(foo : string) {} var x = function (foo: string) {} // Options: ["always"] var x = function (foo : string) {} class X { foo({ bar }: Props = this.props) {} } class Foo { constructor(foo: string ) {} } // Options: ["always"] class Foo { constructor(foo : string ) {} } async function foo({ lorem, ipsum, dolor }: SomeType) {} function x({ a, b }: { a: string, b: number }) {} function a(): x {} // Options: ["always"] function a() : x {} function a(): (number | string) {} // Options: ["always"] function a() : (number | string) {} type X = (foo:string) => number; type X = (foo: string) => number; type X = (foo: ?string) => number; type X = (foo?: string) => number; type X = (foo?: ?string) => number; type X = (foo ?: string) => number; // Options: ["always"] type X = (foo? : string) => number // Options: ["always"] type X = (foo? : ?string) => number class Foo { bar } class Foo { bar = 3 } class Foo { bar: string } class Foo { bar: ?string } class Foo { bar:?string } // Options: ["always"] class Foo { bar : string } class X { static foo:number } class X { static foo: number } // Options: ["always"] class X { static foo :number } // Options: ["always"] class X { static foo : number } declare class Foo { static bar:number; } // Options: ["always"] declare class Foo { static bar :number; } declare class Foo { static bar: number; } // Options: ["always"] declare class Foo { static bar : number; } class X { +foo: string } class X { static +foo: string } // Options: ["always"] class X { +foo : string } // Options: ["always"] class X { static +foo : string } type X = { foo: string } // Options: ["always"] type X = { foo : string } type X = { foo?: string } type X = { foo ?: string } // Options: ["always"] type X = { foo? : string } type X = { +foo: string } type X = { +foo?: string } // Options: ["always"] type X = { +foo : string } // Options: ["always"] type X = { +foo? : string } // Options: ["always"] type X = { [a : b] : c } // Options: ["never"] type X = { [a:b]:c } // Options: ["always"] type X = { +[a : b] : c } // Options: ["never"] type X = { +[a:b]:c } // Options: ["always"] type X = { [a : (b)] : (c) } // Options: ["never"] type X = { [a:(b)]:(c) } // Options: ["never"] const x = ({}:{}) // Options: ["always"] const x = ({} :{}) // Options: ["never"] ((x): string) // Options: ["always"] ((x) : string) ``` ### type-id-match Enforces a consistent naming pattern for type aliases. #### Options This rule needs a text RegExp to operate with Its signature is as follows: ```js { "rules": { "flowtype/type-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 type foo = {}; // Message: Type identifier 'foo' does not match pattern '/^([A-Z][a-z0-9]*)+Type$/'. // Options: ["^foo$"] type FooType = {}; // Message: Type identifier 'FooType' does not match pattern '/^foo$/'. ``` The following patterns are not considered problems: ```js type FooType = {}; // Options: ["^foo$"] type foo = {}; ``` ### union-intersection-spacing _The `--fix` option on the command line automatically fixes problems reported by this rule._ Enforces consistent spacing around union and intersection type separators (`|` and `&`). This rule takes one argument. If it is `'always'` then a problem is raised when there is no space around the separator. If it is `'never'` then a problem is raised when there is a space around the separator. The default value is `'always'`. The following patterns are considered problems: ```js type X = string| number; // Message: There must be a space before union type annotation separator // Options: ["always"] type X = string| number; // Message: There must be a space before union type annotation separator type X = string |number; // Message: There must be a space after union type annotation separator type X = string|number; // Message: There must be a space before union type annotation separator // Message: There must be a space after union type annotation separator type X = {x: string}|{y: number}; // Message: There must be a space before union type annotation separator // Message: There must be a space after union type annotation separator type X = string | number |boolean; // Message: There must be a space after union type annotation separator type X = string|number|boolean; // Message: There must be a space before union type annotation separator // Message: There must be a space after union type annotation separator // Message: There must be a space before union type annotation separator // Message: There must be a space after union type annotation separator type X = (string)| number; // Message: There must be a space before union type annotation separator type X = ((string))|(number | foo); // Message: There must be a space before union type annotation separator // Message: There must be a space after union type annotation separator // Options: ["never"] type X = string |number; // Message: There must be no space before union type annotation separator // Options: ["never"] type X = string| number; // Message: There must be no space after union type annotation separator type X = string& number; // Message: There must be a space before intersection type annotation separator // Options: ["always"] type X = string& number; // Message: There must be a space before intersection type annotation separator type X = string &number; // Message: There must be a space after intersection type annotation separator type X = {x: string}&{y: number}; // Message: There must be a space before intersection type annotation separator // Message: There must be a space after intersection type annotation separator type X = string&number; // Message: There must be a space before intersection type annotation separator // Message: There must be a space after intersection type annotation separator type X = string & number &boolean; // Message: There must be a space after intersection type annotation separator type X = string&number&boolean; // Message: There must be a space before intersection type annotation separator // Message: There must be a space after intersection type annotation separator // Message: There must be a space before intersection type annotation separator // Message: There must be a space after intersection type annotation separator type X = (string)& number; // Message: There must be a space before intersection type annotation separator type X = ((string))&(number & foo); // Message: There must be a space before intersection type annotation separator // Message: There must be a space after intersection type annotation separator // Options: ["never"] type X = string &number; // Message: There must be no space before intersection type annotation separator // Options: ["never"] type X = string& number; // Message: There must be no space after intersection type annotation separator ``` The following patterns are not considered problems: ```js type X = string | number; type X = string | number | boolean; type X = (string) | number; type X = ((string)) | (number | foo); // Options: ["never"] type X = string|number type X = | string | number function x() { type X = | string | number } type X = string & number; type X = string & number & boolean; type X = (string) & number; type X = ((string)) & (number & foo); // Options: ["never"] type X = string&number type X = & string & number function x() { type X = & string & number } ``` ### use-flow-type Marks Flow [type alias](https://flowtype.org/docs/type-aliases.html) declarations as used. Used to suppress [`no-unused-vars`](http://eslint.org/docs/rules/no-unused-vars) errors that are triggered by type aliases. The following patterns are not considered problems: ```js declare class A {} // Additional rules: {"no-unused-vars":1} declare function A(): Y // Additional rules: {"no-unused-vars":1} declare module A {} // Additional rules: {"no-unused-vars":1} declare module A { declare var a: Y } // Additional rules: {"no-unused-vars":1} declare var A: Y // Additional rules: {"no-unused-vars":1} import type A from "a"; (function(): T {}) // Additional rules: {"no-unused-vars":1} (function(): T {}); import type A from "a" // Additional rules: {"no-unused-vars":1} import type {A} from "a"; (function(): T {}) // Additional rules: {"no-unused-vars":1} (function(): T {}); import type {A} from "a" // Additional rules: {"no-unused-vars":1} (function(): T {}); import type {a as A} from "a" // Additional rules: {"no-unused-vars":1} type A = {}; function x(i: Y) { i }; x() // Additional rules: {"no-unused-vars":1} function x(i: Y) { i }; type A = {}; x() // Additional rules: {"no-unused-vars":1} type A = {}; function x(i: Y) { i }; x() // Additional rules: {"no-unused-vars":1} function x(i: Y) { i }; type A = {}; x() // Additional rules: {"no-unused-vars":1} ``` ### valid-syntax **Deprecated** Babylon (the Babel parser) v6.10.0 fixes parsing of the invalid syntax this plugin warned against. Checks for simple Flow syntax errors. eslint-plugin-flowtype-2.25.0/bin/000077500000000000000000000000001300375303300170065ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/bin/readmeAssertions.js000066400000000000000000000045511300375303300226610ustar00rootroot00000000000000/** * This script is used to inline assertions into the README.md documents. */ import _ from 'lodash'; import glob from 'glob'; import path from 'path'; import fs from 'fs'; const formatCodeSnippet = (setup) => { const paragraphs = []; if (setup.options) { paragraphs.push('// Options: ' + JSON.stringify(setup.options)); } paragraphs.push(setup.code); if (setup.errors) { setup.errors.forEach((message) => { paragraphs.push('// Message: ' + message.message); }); } if (setup.rules) { paragraphs.push('// Additional rules: ' + JSON.stringify(setup.rules)); } return paragraphs.join('\n'); }; const getAssertions = () => { const assertionFiles = glob.sync(path.resolve(__dirname, './../tests/rules/assertions/*.js')); const assertionNames = _.map(assertionFiles, (filePath) => { return path.basename(filePath, '.js'); }); const assertionCodes = _.map(assertionFiles, (filePath) => { const codes = require(filePath); return { valid: _.map(codes.valid, formatCodeSnippet), invalid: _.map(codes.invalid, formatCodeSnippet) }; }); return _.zipObject(assertionNames, assertionCodes); }; const updateDocuments = (assertions) => { const readmeDocumentPath = path.join(__dirname, './../README.md'); let documentBody = fs.readFileSync(readmeDocumentPath, 'utf8'); documentBody = documentBody.replace(//ig, (assertionsBlock) => { let exampleBody; const ruleName = assertionsBlock.match(/assertions ([a-z]+)/i)[1]; const ruleAssertions = assertions[ruleName]; if (!ruleAssertions) { throw new Error('No assertions available for rule "' + ruleName + '".'); return assertionsBlock; } exampleBody = ''; if (ruleAssertions.invalid.length) { exampleBody += 'The following patterns are considered problems:\n\n```js\n' + ruleAssertions.invalid.join('\n\n') + '\n```\n\n'; } if (ruleAssertions.valid.length) { exampleBody += 'The following patterns are not considered problems:\n\n```js\n' + ruleAssertions.valid.join('\n\n') + '\n```\n\n'; } return exampleBody; }); fs.writeFileSync(readmeDocumentPath, documentBody); }; updateDocuments(getAssertions()); eslint-plugin-flowtype-2.25.0/package.json000066400000000000000000000034411300375303300205260ustar00rootroot00000000000000{ "name": "eslint-plugin-flowtype", "description": "Flowtype linting rules for ESLint.", "version": "2.25.0", "main": "./dist/index.js", "repository": { "type": "git", "url": "https://github.com/gajus/eslint-plugin-flowtype" }, "keywords": [ "eslint", "plugin", "flowtype" ], "author": { "name": "Gajus Kuizinas", "email": "gajus@gajus.com", "url": "http://gajus.com" }, "license": "BSD-3-Clause", "peerDependencies": { "eslint": ">=2.0.0" }, "dependencies": { "lodash": "^4.15.0" }, "scripts": { "lint": "eslint ./src ./tests", "test": "mocha --compilers js:babel-register ./tests/rules/index.js", "build": "babel ./src --out-dir ./dist --copy-files", "documentation-add-assertions": "babel-node ./bin/readmeAssertions", "documentation": "gitdown ./.README/README.md --output-file ./README.md; npm run documentation-add-assertions", "create-index": "create-index ./src --update-index", "precommit": "npm run lint && npm run test && npm run format-json", "commitmsg": "conventional-changelog-lint -e", "format-json": "jsonlint --sort-keys --in-place --indent ' ' ./src/configs/recommended.json && echo '' >> ./src/configs/recommended.json" }, "devDependencies": { "babel-cli": "^6.14.0", "babel-eslint": "^6.1.2", "babel-plugin-add-module-exports": "^0.2.1", "babel-preset-es2015": "^6.14.0", "babel-preset-stage-0": "^6.5.0", "babel-register": "^6.14.0", "chai": "^3.5.0", "conventional-changelog-lint": "^1.0.1", "create-index": "^0.1.3", "eslint": "^3.4.0", "eslint-config-canonical": "1.8.1", "gitdown": "^2.5.0", "husky": "^0.11.7", "jsonlint": "^1.6.2", "mocha": "^3.0.2", "standard-version": "^2.4.0", "travis-after-all": "^1.4.4" } } eslint-plugin-flowtype-2.25.0/src/000077500000000000000000000000001300375303300170255ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/src/configs/000077500000000000000000000000001300375303300204555ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/src/configs/recommended.json000066400000000000000000000016261300375303300236370ustar00rootroot00000000000000{ "parser": "babel-eslint", "rules": { "flowtype/boolean-style": [ 2, "boolean" ], "flowtype/define-flow-type": 1, "flowtype/delimiter-dangle": 0, "flowtype/generic-spacing": [ 2, "never" ], "flowtype/no-weak-types": 0, "flowtype/require-parameter-type": 0, "flowtype/require-return-type": 0, "flowtype/require-valid-file-annotation": 0, "flowtype/semi": 0, "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": 0, "flowtype/union-intersection-spacing": [ 2, "always" ], "flowtype/use-flow-type": 1, "flowtype/valid-syntax": 1 }, "settings": { "flowtype": { "onlyFilesWithFlowAnnotation": false } } } eslint-plugin-flowtype-2.25.0/src/index.js000066400000000000000000000046751300375303300205060ustar00rootroot00000000000000import defineFlowType from './rules/defineFlowType'; import genericSpacing from './rules/genericSpacing'; import noWeakTypes from './rules/noWeakTypes'; import requireParameterType from './rules/requireParameterType'; import requireReturnType from './rules/requireReturnType'; import requireValidFileAnnotation from './rules/requireValidFileAnnotation'; import semi from './rules/semi'; import spaceAfterTypeColon from './rules/spaceAfterTypeColon'; import spaceBeforeGenericBracket from './rules/spaceBeforeGenericBracket'; import spaceBeforeTypeColon from './rules/spaceBeforeTypeColon'; import unionIntersectionSpacing from './rules/unionIntersectionSpacing'; import typeIdMatch from './rules/typeIdMatch'; import useFlowType from './rules/useFlowType'; import validSyntax from './rules/validSyntax'; import booleanStyle from './rules/booleanStyle'; import delimiterDangle from './rules/delimiterDangle'; import noDupeKeys from './rules/noDupeKeys'; import sortKeys from './rules/sortKeys'; import objectTypeDelimiter from './rules/objectTypeDelimiter'; import recommended from './configs/recommended.json'; export default { configs: { recommended }, rules: { 'boolean-style': booleanStyle, 'define-flow-type': defineFlowType, 'delimiter-dangle': delimiterDangle, 'generic-spacing': genericSpacing, 'no-dupe-keys': noDupeKeys, 'no-weak-types': noWeakTypes, 'object-type-delimiter': objectTypeDelimiter, 'require-parameter-type': requireParameterType, 'require-return-type': requireReturnType, 'require-valid-file-annotation': requireValidFileAnnotation, semi, 'sort-keys': sortKeys, 'space-after-type-colon': spaceAfterTypeColon, 'space-before-generic-bracket': spaceBeforeGenericBracket, 'space-before-type-colon': spaceBeforeTypeColon, 'type-id-match': typeIdMatch, 'union-intersection-spacing': unionIntersectionSpacing, 'use-flow-type': useFlowType, 'valid-syntax': validSyntax }, rulesConfig: { 'boolean-style': 0, 'define-flow-type': 0, 'delimiter-dangle': 0, 'generic-spacing': 0, 'no-dupe-keys': 0, 'no-weak-types': 0, 'object-type-delimiter': 0, 'require-parameter-type': 0, 'require-return-type': 0, semi: 0, 'sort-keys': 0, 'space-after-type-colon': 0, 'space-before-generic-bracket': 0, 'space-before-type-colon': 0, 'type-id-match': 0, 'union-intersection-spacing': 0, 'use-flow-type': 0, 'valid-syntax': 0 } }; eslint-plugin-flowtype-2.25.0/src/rules/000077500000000000000000000000001300375303300201575ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/src/rules/booleanStyle.js000066400000000000000000000012411300375303300231530ustar00rootroot00000000000000export default (context) => { const longForm = (context.options[0] || 'boolean') === 'boolean'; return { BooleanTypeAnnotation (node) { const diff = node.end - node.start; if (longForm && diff === 4) { context.report({ fix (fixer) { return fixer.replaceText(node, 'boolean'); }, message: 'Use "boolean", not "bool"', node }); } if (!longForm && diff !== 4) { context.report({ fix (fixer) { return fixer.replaceText(node, 'bool'); }, message: 'Use "bool", not "boolean"', node }); } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/defineFlowType.js000066400000000000000000000035411300375303300234440ustar00rootroot00000000000000export const schema = []; export default (context) => { let globalScope; // do nearly the same thing that eslint does for config globals // https://github.com/eslint/eslint/blob/v2.0.0/lib/eslint.js#L118-L194 const makeDefined = (ident) => { let ii; // start from the right since we're going to remove items from the array for (ii = globalScope.through.length - 1; ii >= 0; ii--) { const ref = globalScope.through[ii]; if (ref.identifier.name === ident.name) { // use "__defineGeneric" since we don't have a reference to "escope.Variable" globalScope.__defineGeneric( // eslint-disable-line no-underscore-dangle ident.name, globalScope.set, globalScope.variables ); const variable = globalScope.set.get(ident.name); variable.writeable = false; // "through" contains all references whose definition cannot be found // so we need to update references and remove the ones that were added globalScope.through.splice(ii, 1); ref.resolved = variable; variable.references.push(ref); } } }; return { ClassImplements (node) { makeDefined(node.id); }, GenericTypeAnnotation (node) { if (node.id.type === 'Identifier') { makeDefined(node.id); } else if (node.id.type === 'QualifiedTypeIdentifier') { let qid; qid = node.id; do { qid = qid.qualification; } while (qid.qualification); makeDefined(qid); } }, InterfaceDeclaration (node) { makeDefined(node.id); }, Program () { globalScope = context.getScope(); }, TypeParameterDeclaration (node) { node.params.forEach((param) => { makeDefined(param); }); } }; }; eslint-plugin-flowtype-2.25.0/src/rules/delimiterDangle.js000066400000000000000000000043531300375303300236130ustar00rootroot00000000000000import _ from 'lodash'; export default (context) => { const option = context.options[0] || 'never'; const sourceCode = context.getSourceCode(); const reporter = (node, message, fix) => { return () => { context.report({ fix, message, node }); }; }; const makeReporters = (node, tokenToFix) => { return { dangle: reporter(node, 'Unexpected trailing delimiter', (fixer) => { return fixer.replaceText(tokenToFix, ''); }), noDangle: reporter(node, 'Missing trailing delimiter', (fixer) => { return fixer.insertTextAfter(tokenToFix, ','); }) }; }; const evaluate = (node, lastChildNode) => { if (!lastChildNode) { return; } const [penultimateToken, lastToken] = sourceCode.getLastTokens(node, 2); const isDangling = [';', ','].indexOf(penultimateToken.value) > -1; const isMultiLine = penultimateToken.loc.start.line !== lastToken.loc.start.line; const report = makeReporters(lastChildNode, penultimateToken); if (option === 'always' && !isDangling) { report.noDangle(); return; } if (option === 'never' && isDangling) { report.dangle(); return; } if (option === 'always-multiline' && !isDangling && isMultiLine) { report.noDangle(); return; } if (option === 'always-multiline' && isDangling && !isMultiLine) { report.dangle(); return; } if (option === 'only-multiline' && isDangling && !isMultiLine) { report.dangle(); return; } }; // required for reporting the correct position const getLast = (property, indexer) => { if (!property) { return indexer; } if (!indexer) { return property; } if (property.loc.end.line > indexer.loc.end.line) { return property; } if (indexer.loc.end.line > property.loc.end.line) { return indexer; } if (property.loc.end.column > indexer.loc.end.column) { return property; } return indexer; }; return { ObjectTypeAnnotation (node) { evaluate(node, getLast(_.last(node.properties), _.last(node.indexers))); }, TupleTypeAnnotation (node) { evaluate(node, _.last(node.types)); } }; }; eslint-plugin-flowtype-2.25.0/src/rules/genericSpacing.js000066400000000000000000000051671300375303300234470ustar00rootroot00000000000000import {spacingFixers} from './../utilities'; export default (context) => { const sourceCode = context.getSourceCode(); const never = (context.options[0] || 'never') === 'never'; return { GenericTypeAnnotation (node) { const types = node.typeParameters; // Promise // ^^^^^^^^^^^^ GenericTypeAnnotation (with typeParameters) // ^^^ GenericTypeAnnotation (without typeParameters) if (!types) { return; } const [opener, firstInnerToken] = sourceCode.getFirstTokens(types, 2); const [lastInnerToken, closer] = sourceCode.getLastTokens(types, 2); const spacesBefore = firstInnerToken.start - opener.end; const spacesAfter = closer.start - lastInnerToken.end; if (never) { if (spacesBefore) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(opener, spacesBefore), message: 'There must be no space at start of "{{name}}" generic type annotation', node: types }); } if (spacesAfter) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(lastInnerToken, spacesAfter), message: 'There must be no space at end of "{{name}}" generic type annotation', node: types }); } } else { if (spacesBefore > 1) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(opener, spacesBefore - 1), message: 'There must be one space at start of "{{name}}" generic type annotation', node: types }); } else if (spacesBefore === 0) { context.report({ data: {name: node.id.name}, fix: spacingFixers.addSpaceAfter(opener), message: 'There must be a space at start of "{{name}}" generic type annotation', node: types }); } if (spacesAfter > 1) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(lastInnerToken, spacesAfter - 1), message: 'There must be one space at end of "{{name}}" generic type annotation', node: types }); } else if (spacesAfter === 0) { context.report({ data: {name: node.id.name}, fix: spacingFixers.addSpaceAfter(lastInnerToken), message: 'There must be a space at end of "{{name}}" generic type annotation', node: types }); } } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/noDupeKeys.js000066400000000000000000000011721300375303300226040ustar00rootroot00000000000000import _ from 'lodash/'; import { getParameterName } from './../utilities'; export default (context) => { const report = (node) => { context.report({ loc: node.loc, message: 'Duplicate property.', node }); }; const checkForDuplicates = (node) => { const haystack = []; _.forEach(node.properties, (identifierNode) => { const needle = getParameterName(identifierNode, context); if (_.includes(haystack, needle)) { report(identifierNode); } else { haystack.push(needle); } }); }; return { ObjectTypeAnnotation: checkForDuplicates }; }; eslint-plugin-flowtype-2.25.0/src/rules/noWeakTypes.js000066400000000000000000000020231300375303300227630ustar00rootroot00000000000000import _ from 'lodash'; const reportWeakType = (context, weakType) => { return (node) => { context.report({ data: {weakType}, message: 'Unexpected use of weak type "{{weakType}}"', node }); }; }; const genericTypeEvaluator = (context, {checkFunction, checkObject}) => { return (node) => { const name = _.get(node, 'id.name'); if (checkFunction && name === 'Function' || checkObject && name === 'Object') { reportWeakType(context, name)(node); } }; }; export default (context) => { const checkAny = _.get(context, 'options[0].any', true) === true; const checkFunction = _.get(context, 'options[0].Function', true) === true; const checkObject = _.get(context, 'options[0].Object', true) === true; const checks = {}; if (checkAny) { checks.AnyTypeAnnotation = reportWeakType(context, 'any'); } if (checkFunction || checkObject) { checks.GenericTypeAnnotation = genericTypeEvaluator(context, { checkFunction, checkObject }); } return checks; }; eslint-plugin-flowtype-2.25.0/src/rules/objectTypeDelimiter.js000066400000000000000000000024221300375303300244640ustar00rootroot00000000000000 // ported from babel/flow-object-type; original author: Nat Mote // https://github.com/babel/eslint-plugin-babel/blob/c0a49d25a97feb12c1d07073a0b37317359a5fe5/rules/flow-object-type.js const SEMICOLON = { char: ';', name: 'semicolon' }; const COMMA = { char: ',', name: 'comma' }; const create = (context) => { let GOOD; let BAD; if (!context.options[0] || context.options[0] === COMMA.name) { GOOD = COMMA; BAD = SEMICOLON; } else { GOOD = SEMICOLON; BAD = COMMA; } const requireProperPunctuation = (node) => { const tokens = context.getSourceCode().getTokens(node); const lastToken = tokens[tokens.length - 1]; if (lastToken.type === 'Punctuator') { if (lastToken.value === BAD.char) { context.report({ fix (fixer) { return fixer.replaceText(lastToken, GOOD.char); }, message: 'Prefer ' + GOOD.name + 's to ' + BAD.name + 's in object and class types', node: lastToken }); } } }; return { ObjectTypeCallProperty: requireProperPunctuation, ObjectTypeIndexer: requireProperPunctuation, ObjectTypeProperty: requireProperPunctuation }; }; const schema = [ { enum: ['semicolon', 'comma'] } ]; export default { create, schema }; eslint-plugin-flowtype-2.25.0/src/rules/requireParameterType.js000066400000000000000000000026111300375303300246740ustar00rootroot00000000000000import _ from 'lodash'; import { getParameterName, isFlowFile, iterateFunctionNodes, quoteName } from './../utilities'; export default iterateFunctionNodes((context) => { const checkThisFile = !_.get(context, 'settings.flowtype.onlyFilesWithFlowAnnotation') || isFlowFile(context); if (!checkThisFile) { return () => {}; } const skipArrows = _.get(context, 'options[0].excludeArrowFunctions'); const excludeParameterMatch = new RegExp(_.get(context, 'options[0].excludeParameterMatch', 'a^')); return (functionNode) => { _.forEach(functionNode.params, (identifierNode) => { const parameterName = getParameterName(identifierNode, context); if (excludeParameterMatch.test(parameterName)) { return; } const typeAnnotation = _.get(identifierNode, 'typeAnnotation') || _.get(identifierNode, 'left.typeAnnotation'); const isArrow = functionNode.type === 'ArrowFunctionExpression'; const isArrowFunctionExpression = functionNode.expression; if (skipArrows === 'expressionsOnly' && isArrowFunctionExpression || skipArrows === true && isArrow) { return; } if (!typeAnnotation) { context.report({ data: { name: quoteName(parameterName) }, message: 'Missing {{name}}parameter type annotation.', node: identifierNode }); } }); }; }); eslint-plugin-flowtype-2.25.0/src/rules/requireReturnType.js000066400000000000000000000064731300375303300242450ustar00rootroot00000000000000import _ from 'lodash'; import { isFlowFile } from './../utilities'; export default (context) => { const checkThisFile = !_.get(context, 'settings.flowtype.onlyFilesWithFlowAnnotation') || isFlowFile(context); if (!checkThisFile) { return () => {}; } const annotateReturn = (_.get(context, 'options[0]') || 'always') === 'always'; const annotateUndefined = (_.get(context, 'options[1].annotateUndefined') || 'never') === 'always'; const skipArrows = _.get(context, 'options[1].excludeArrowFunctions') || false; const targetNodes = []; const registerFunction = (functionNode) => { targetNodes.push({ functionNode }); }; const isUndefinedReturnType = (returnNode) => { return returnNode.argument === null || returnNode.argument.name === 'undefined' || returnNode.argument.operator === 'void'; }; const getIsReturnTypeAnnotationUndefined = (targetNode) => { const isReturnTypeAnnotationLiteralUndefined = _.get(targetNode, 'functionNode.returnType.typeAnnotation.id.name') === 'undefined' && _.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'GenericTypeAnnotation'; const isReturnTypeAnnotationVoid = _.get(targetNode, 'functionNode.returnType.typeAnnotation.type') === 'VoidTypeAnnotation'; return isReturnTypeAnnotationLiteralUndefined || isReturnTypeAnnotationVoid; }; const evaluateFunction = (functionNode) => { const targetNode = targetNodes.pop(); if (functionNode !== targetNode.functionNode) { throw new Error('Mismatch.'); } const isArrow = functionNode.type === 'ArrowFunctionExpression'; const isArrowFunctionExpression = functionNode.expression; const hasImplicitReturnType = functionNode.async || functionNode.generator; const isFunctionReturnUndefined = !isArrowFunctionExpression && !hasImplicitReturnType && (!targetNode.returnStatementNode || isUndefinedReturnType(targetNode.returnStatementNode)); const isReturnTypeAnnotationUndefined = getIsReturnTypeAnnotationUndefined(targetNode); if (skipArrows === 'expressionsOnly' && isArrowFunctionExpression || skipArrows === true && isArrow) { return; } if (isFunctionReturnUndefined && isReturnTypeAnnotationUndefined && !annotateUndefined) { context.report(functionNode, 'Must not annotate undefined return type.'); } else if (isFunctionReturnUndefined && !isReturnTypeAnnotationUndefined && annotateUndefined) { context.report(functionNode, 'Must annotate undefined return type.'); } else if (!isFunctionReturnUndefined && !isReturnTypeAnnotationUndefined) { if (annotateReturn && !functionNode.returnType) { context.report(functionNode, 'Missing return type annotation.'); } } }; const evaluateNoise = () => { targetNodes.pop(); }; return { ArrowFunctionExpression: registerFunction, 'ArrowFunctionExpression:exit': evaluateFunction, ClassDeclaration: registerFunction, 'ClassDeclaration:exit': evaluateNoise, ClassExpression: registerFunction, 'ClassExpression:exit': evaluateNoise, FunctionDeclaration: registerFunction, 'FunctionDeclaration:exit': evaluateFunction, FunctionExpression: registerFunction, 'FunctionExpression:exit': evaluateFunction, ReturnStatement: (node) => { targetNodes[targetNodes.length - 1].returnStatementNode = node; } }; }; eslint-plugin-flowtype-2.25.0/src/rules/requireValidFileAnnotation.js000066400000000000000000000034041300375303300260050ustar00rootroot00000000000000import _ from 'lodash'; import { isFlowFile, isFlowFileAnnotation } from './../utilities'; const defaults = { annotationStyle: 'none' }; const looksLikeFlowFileAnnotation = (comment) => { return /@(?:no)?flow/i.test(comment); }; const isValidAnnotationStyle = (node, style) => { if (style === 'none') { return true; } return style === node.type.toLowerCase(); }; export const schema = [ { enum: ['always'] } ]; export default (context) => { const checkThisFile = !_.get(context, 'settings.flowtype.onlyFilesWithFlowAnnotation') || isFlowFile(context); if (!checkThisFile) { return {}; } const always = context.options[0] === 'always'; const style = _.get(context, 'options[1].annotationStyle', defaults.annotationStyle); return { Program (node) { const firstToken = node.tokens[0]; const potentialFlowFileAnnotation = _.find(context.getAllComments(), (comment) => { return looksLikeFlowFileAnnotation(comment.value); }); if (potentialFlowFileAnnotation) { if (firstToken && firstToken.start < potentialFlowFileAnnotation.start) { context.report(potentialFlowFileAnnotation, 'Flow file annotation not at the top of the file.'); } if (!isFlowFileAnnotation(potentialFlowFileAnnotation.value)) { context.report(potentialFlowFileAnnotation, 'Malformed flow file annotation.'); } if (!isValidAnnotationStyle(potentialFlowFileAnnotation, style)) { const str = style === 'line' ? '`// @flow`' : '`/* @flow */`'; context.report(potentialFlowFileAnnotation, 'Flow file annotation style must be ' + str); } } else if (always) { context.report(node, 'Flow file annotation is missing.'); } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/semi.js000066400000000000000000000021711300375303300214530ustar00rootroot00000000000000export default (context) => { const never = (context.options[0] || 'always') === 'never'; const sourceCode = context.getSourceCode(); const report = (node, missing) => { const lastToken = sourceCode.getLastToken(node); let fix, message; let {loc} = lastToken; if (missing) { message = 'Missing semicolon.'; loc = loc.end; fix = (fixer) => { return fixer.insertTextAfter(lastToken, ';'); }; } else { message = 'Extra semicolon.'; loc = loc.start; fix = (fixer) => { return fixer.remove(lastToken); }; } context.report({ fix, loc, message, node }); }; const isSemicolon = (token) => { return token.type === 'Punctuator' && token.value === ';'; }; const checkForSemicolon = (node) => { const lastToken = sourceCode.getLastToken(node); const isLastTokenSemicolon = isSemicolon(lastToken); if (never && isLastTokenSemicolon) { report(node, false); } if (!never && !isLastTokenSemicolon) { report(node, true); } }; return { TypeAlias: checkForSemicolon }; }; eslint-plugin-flowtype-2.25.0/src/rules/sortKeys.js000066400000000000000000000044121300375303300223410ustar00rootroot00000000000000import _ from 'lodash'; import { getParameterName } from './../utilities'; const defaults = { caseSensitive: true, natural: false }; /** * Functions to compare the order of two strings * * Based on a similar function from eslint's sort-keys rule. * https://github.com/eslint/eslint/blob/master/lib/rules/sort-keys.js * * @private */ const isValidOrders = { asc (str1, str2) { return str1 <= str2; }, ascI (str1, str2) { return str1.toLowerCase() <= str2.toLowerCase(); }, ascIN (str1, str2) { return isValidOrders.naturalCompare(str1.toLowerCase(), str2.toLowerCase()) <= 0; }, ascN (str1, str2) { return isValidOrders.naturalCompare(str1, str2) <= 0; }, desc (str1, str2) { return isValidOrders.asc(str2, str1); }, descI (str1, str2) { return isValidOrders.ascI(str2, str1); }, descIN (str1, str2) { return isValidOrders.ascIN(str2, str1); }, descN (str1, str2) { return isValidOrders.ascN(str2, str1); }, naturalCompare (str1, str2) { return str1.localeCompare(str2, 'en-US', {numeric: true}); } }; export default (context) => { const order = _.get(context, ['options', 0], 'asc'); const {natural, caseSensitive} = _.get(context, ['options', 1], defaults); const insensitive = caseSensitive === false; let prev; const checkKeyOrder = (node) => { prev = null; _.forEach(node.properties, (identifierNode) => { const current = getParameterName(identifierNode, context); const last = prev; // keep track of the last token prev = current || last; if (!last || !current) { return; } const isValidOrder = isValidOrders[order + (insensitive ? 'I' : '') + (natural ? 'N' : '')]; if (isValidOrder(last, current) === false) { context.report({ data: { current, insensitive: insensitive ? 'insensitive ' : '', last, natural: natural ? 'natural ' : '', order }, loc: identifierNode.loc, message: 'Expected type annotations to be in {{natural}}{{insensitive}}{{order}}ending order. "{{current}}" should be before "{{last}}".', node: identifierNode }); } }); }; return { ObjectTypeAnnotation: checkKeyOrder }; }; eslint-plugin-flowtype-2.25.0/src/rules/spaceAfterTypeColon.js000066400000000000000000000002711300375303300244270ustar00rootroot00000000000000import makeSpacing from './typeColonSpacing'; export default (context) => { return makeSpacing('after', context, { always: (context.options[0] || 'always') === 'always' }); }; eslint-plugin-flowtype-2.25.0/src/rules/spaceBeforeGenericBracket.js000066400000000000000000000025661300375303300255350ustar00rootroot00000000000000import {spacingFixers} from '../utilities'; export default (context) => { const never = (context.options[0] || 'never') === 'never'; return { GenericTypeAnnotation (node) { const types = node.typeParameters; // Promise // ^^^^^^^^^^^^ GenericTypeAnnotation (with typeParameters) // ^^^ GenericTypeAnnotation (without typeParameters) if (!types) { return; } const spaceBefore = types.start - node.id.end; if (never && spaceBefore) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(node.id, spaceBefore), message: 'There must be no space before "{{name}}" generic type annotation bracket', node }); } if (!never && !spaceBefore) { context.report({ data: {name: node.id.name}, fix: spacingFixers.addSpaceAfter(node.id), message: 'There must be a space before "{{name}}" generic type annotation bracket', node }); } if (!never && spaceBefore > 1) { context.report({ data: {name: node.id.name}, fix: spacingFixers.stripSpacesAfter(node.id, spaceBefore - 1), message: 'There must be one space before "{{name}}" generic type annotation bracket', node }); } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/spaceBeforeTypeColon.js000066400000000000000000000002541300375303300245710ustar00rootroot00000000000000import makeSpacing from './typeColonSpacing'; export default (context) => { return makeSpacing('before', context, { always: context.options[0] === 'always' }); }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/000077500000000000000000000000001300375303300234405ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateFunctions.js000066400000000000000000000007571300375303300275060ustar00rootroot00000000000000import _ from 'lodash'; import {iterateFunctionNodes} from '../../utilities'; import evaluateTypical from './evaluateTypical'; import evaluateReturnType from './evaluateReturnType'; export default iterateFunctionNodes((context, report) => { const checkParam = evaluateTypical(context, report, 'parameter'); const checkReturnType = evaluateReturnType(context, report); return (functionNode) => { _.forEach(functionNode.params, checkParam); checkReturnType(functionNode); }; }); eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateObjectTypeIndexer.js000066400000000000000000000011031300375303300311070ustar00rootroot00000000000000import {getTokenAfterParens, getTokenBeforeParens} from '../../utilities'; export default (context, report) => { const sourceCode = context.getSourceCode(); return (objectTypeIndexer) => { // type X = { [a: b]: c } // ^ report({ colon: getTokenBeforeParens(sourceCode, objectTypeIndexer.key), node: objectTypeIndexer }); // type X = { [a: b]: c } // ^ report({ colon: sourceCode.getTokenAfter(getTokenAfterParens(sourceCode, objectTypeIndexer.key)), node: objectTypeIndexer }); }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateObjectTypeProperty.js000066400000000000000000000022661300375303300313500ustar00rootroot00000000000000import {getParameterName, quoteName} from '../../utilities'; const getColon = (context, objectTypeProperty) => { let tokenIndex = 1; // eslint-disable-line init-declarations if (objectTypeProperty.optional) { tokenIndex++; } if (objectTypeProperty.static) { tokenIndex++; } if (objectTypeProperty.variance) { tokenIndex++; } return context.getSourceCode().getFirstToken(objectTypeProperty, tokenIndex); }; // 1) type X = { foo(): A; } // 2) type X = { foo: () => A; } // the above have identical ASTs (save for their ranges) // case 1 doesn't have a type annotation colon and should be ignored const isShortPropertyFunction = (objectTypeProperty) => { return objectTypeProperty.value.type === 'FunctionTypeAnnotation' && objectTypeProperty.start === objectTypeProperty.value.start; }; export default (context, report) => { return (objectTypeProperty) => { if (isShortPropertyFunction(objectTypeProperty)) { // potential difference: not checked in before return; } report({ colon: getColon(context, objectTypeProperty), name: quoteName(getParameterName(objectTypeProperty, context)), node: objectTypeProperty }); }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateReturnType.js000066400000000000000000000007711300375303300276530ustar00rootroot00000000000000export default (context, report) => { const sourceCode = context.getSourceCode(); return (functionNode) => { // skip FunctionTypeAnnotation, possibly another rule as it's an arrow, not a colon? // (foo: number) => string // ^^^^ if (functionNode.returnType && functionNode.type !== 'FunctionTypeAnnotation') { report({ colon: sourceCode.getFirstToken(functionNode.returnType), node: functionNode, type: 'return type' }); } }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateTypeCastExpression.js000066400000000000000000000004271300375303300313440ustar00rootroot00000000000000export default (context, report) => { const sourceCode = context.getSourceCode(); return (typeCastExpression) => { report({ colon: sourceCode.getFirstToken(typeCastExpression.typeAnnotation), node: typeCastExpression, type: 'type cast' }); }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateTypical.js000066400000000000000000000014131300375303300271310ustar00rootroot00000000000000import _ from 'lodash'; import {getParameterName, quoteName} from '../../utilities'; export default (context, report, typeForMessage) => { const sourceCode = context.getSourceCode(); const getColon = (node, typeAnnotation) => { if (node.type === 'FunctionTypeParam') { return sourceCode.getFirstToken(node, node.optional ? 2 : 1); } else { return sourceCode.getFirstToken(typeAnnotation); } }; return (node) => { const typeAnnotation = _.get(node, 'typeAnnotation') || _.get(node, 'left.typeAnnotation'); if (typeAnnotation) { report({ colon: getColon(node, typeAnnotation), name: quoteName(getParameterName(node, context)), node, type: typeForMessage + ' type annotation' }); } }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/index.js000066400000000000000000000014311300375303300251040ustar00rootroot00000000000000import reporter from './reporter'; import evaluateObjectTypeIndexer from './evaluateObjectTypeIndexer'; import evaluateObjectTypeProperty from './evaluateObjectTypeProperty'; import evaluateTypeCastExpression from './evaluateTypeCastExpression'; import evaluateTypical from './evaluateTypical'; import evaluateFunctions from './evaluateFunctions'; export default (direction, context, options) => { const report = reporter(direction, context, options); return { ...evaluateFunctions(context, report), ClassProperty: evaluateTypical(context, report, 'class property'), ObjectTypeIndexer: evaluateObjectTypeIndexer(context, report), ObjectTypeProperty: evaluateObjectTypeProperty(context, report), TypeCastExpression: evaluateTypeCastExpression(context, report) }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/reporter.js000066400000000000000000000024271300375303300256450ustar00rootroot00000000000000import {spacingFixers} from '../../utilities'; const getSpaces = (direction, colon, context) => { const sourceCode = context.getSourceCode(); if (direction === 'before') { return colon.start - sourceCode.getTokenBefore(colon).end; } else { return sourceCode.getTokenAfter(colon).start - colon.end; } }; export default (direction, context, {always}) => { return ({colon, node, name = '', type = 'type annotation'}) => { const spaces = getSpaces(direction, colon, context); const data = { direction, name, type }; if (always && spaces > 1) { context.report({ data, fix: spacingFixers.stripSpaces(direction, colon, spaces - 1), message: 'There must be 1 space {{direction}} {{name}}{{type}} colon.', node }); } else if (always && spaces === 0) { context.report({ data, fix: spacingFixers.addSpace(direction, colon), message: 'There must be a space {{direction}} {{name}}{{type}} colon.', node }); } else if (!always && spaces > 0) { context.report({ data, fix: spacingFixers.stripSpaces(direction, colon, spaces), message: 'There must be no space {{direction}} {{name}}{{type}} colon.', node }); } }; }; eslint-plugin-flowtype-2.25.0/src/rules/typeIdMatch.js000066400000000000000000000010241300375303300227250ustar00rootroot00000000000000export const schema = [ { type: 'string' } ]; export default (context) => { const pattern = new RegExp(context.options[0] || '^([A-Z][a-z0-9]*)+Type$'); return { TypeAlias (typeAliasNode) { const typeIdentifierName = typeAliasNode.id.name; if (!pattern.test(typeIdentifierName)) { context.report(typeAliasNode, 'Type identifier \'{{name}}\' does not match pattern \'{{pattern}}\'.', { name: typeIdentifierName, pattern: pattern.toString() }); } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/unionIntersectionSpacing.js000066400000000000000000000036421300375303300255460ustar00rootroot00000000000000import {spacingFixers, getTokenAfterParens} from '../utilities'; export default (context) => { const sourceCode = context.getSourceCode(); const always = (context.options[0] || 'always') === 'always'; const check = (node) => { node.types.forEach((type, index) => { if (index + 1 === node.types.length) { return; } const separator = getTokenAfterParens(sourceCode, type); const endOfType = sourceCode.getTokenBefore(separator); const nextType = sourceCode.getTokenAfter(separator); const spaceBefore = separator.start - endOfType.end; const spaceAfter = nextType.start - separator.end; const data = {type: node.type === 'UnionTypeAnnotation' ? 'union' : 'intersection'}; if (always) { if (!spaceBefore) { context.report({ data, fix: spacingFixers.addSpaceAfter(endOfType), message: 'There must be a space before {{type}} type annotation separator', node }); } if (!spaceAfter) { context.report({ data, fix: spacingFixers.addSpaceAfter(separator), message: 'There must be a space after {{type}} type annotation separator', node }); } } else { if (spaceBefore) { context.report({ data, fix: spacingFixers.stripSpacesAfter(endOfType, spaceBefore), message: 'There must be no space before {{type}} type annotation separator', node }); } if (spaceAfter) { context.report({ data, fix: spacingFixers.stripSpacesAfter(separator, spaceAfter), message: 'There must be no space after {{type}} type annotation separator', node }); } } }); }; return { IntersectionTypeAnnotation: check, UnionTypeAnnotation: check }; }; eslint-plugin-flowtype-2.25.0/src/rules/useFlowType.js000066400000000000000000000016241300375303300230060ustar00rootroot00000000000000export const schema = []; export default (context) => { const markTypeAsUsed = (node) => { context.markVariableAsUsed(node.id.name); }; return { DeclareClass: markTypeAsUsed, DeclareFunction: markTypeAsUsed, DeclareModule: markTypeAsUsed, DeclareVariable: markTypeAsUsed, GenericTypeAnnotation (node) { let typeId; let scope; let variable; if (node.id.type === 'Identifier') { typeId = node.id; } else if (node.id.type === 'QualifiedTypeIdentifier') { typeId = node.id; do { typeId = typeId.qualification; } while (typeId.qualification); } for (scope = context.getScope(); scope; scope = scope.upper) { variable = scope.set.get(typeId.name); if (variable && variable.defs.length) { context.markVariableAsUsed(typeId.name); break; } } } }; }; eslint-plugin-flowtype-2.25.0/src/rules/validSyntax.js000066400000000000000000000016251300375303300230270ustar00rootroot00000000000000import _ from 'lodash'; import { getParameterName, iterateFunctionNodes, quoteName } from './../utilities'; export default iterateFunctionNodes((context) => { return (functionNode) => { _.forEach(functionNode.params, (identifierNode) => { const nodeType = _.get(identifierNode, 'type'); const isAssignmentPattern = nodeType === 'AssignmentPattern'; const hasTypeAnnotation = Boolean(_.get(identifierNode, 'typeAnnotation')); const leftAnnotated = Boolean(_.get(identifierNode, 'left.typeAnnotation')); if (isAssignmentPattern && hasTypeAnnotation && !leftAnnotated) { context.report({ data: { name: quoteName(getParameterName(identifierNode, context)) }, message: '{{name}}parameter type annotation must be placed on left-hand side of assignment.', node: identifierNode }); } }); }; }); eslint-plugin-flowtype-2.25.0/src/utilities/000077500000000000000000000000001300375303300210405ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/src/utilities/getParameterName.js000066400000000000000000000025261300375303300246240ustar00rootroot00000000000000import _ from 'lodash'; export default (identifierNode, context) => { if (_.has(identifierNode, 'name')) { return identifierNode.name; } if (_.has(identifierNode, 'left.name')) { return identifierNode.left.name; } if (_.has(identifierNode, 'key.name')) { return identifierNode.key.name; } if (identifierNode.type === 'RestElement') { return identifierNode.argument.name; } if (identifierNode.type === 'ObjectTypeProperty') { let tokenIndex = 0; // eslint-disable-line init-declarations if (identifierNode.static) { tokenIndex++; } if (identifierNode.variance) { tokenIndex++; } return context.getSourceCode().getFirstToken(identifierNode, tokenIndex).value; } if (identifierNode.type === 'FunctionTypeParam') { return context.getSourceCode().getFirstToken(identifierNode).value; } if (identifierNode.type === 'ObjectPattern' || identifierNode.type === 'ArrayPattern') { const text = context.getSourceCode().getText(identifierNode); if (identifierNode.typeAnnotation) { return text.replace(context.getSourceCode().getText(identifierNode.typeAnnotation), '').trim(); } else { return text; } } if (_.get(identifierNode, 'left.type') === 'ObjectPattern') { return context.getSourceCode().getText(identifierNode.left); } return null; }; eslint-plugin-flowtype-2.25.0/src/utilities/getTokenAfterParens.js000066400000000000000000000004261300375303300253130ustar00rootroot00000000000000const getTokenAfterParens = (sourceCode, node) => { let token; token = sourceCode.getTokenAfter(node); while (token.type === 'Punctuator' && token.value === ')') { token = sourceCode.getTokenAfter(token); } return token; }; export default getTokenAfterParens; eslint-plugin-flowtype-2.25.0/src/utilities/getTokenBeforeParens.js000066400000000000000000000004321300375303300254510ustar00rootroot00000000000000const getTokenBeforeParens = (sourceCode, node) => { let token; token = sourceCode.getTokenBefore(node); while (token.type === 'Punctuator' && token.value === '(') { token = sourceCode.getTokenBefore(token); } return token; }; export default getTokenBeforeParens; eslint-plugin-flowtype-2.25.0/src/utilities/index.js000066400000000000000000000006701300375303300225100ustar00rootroot00000000000000'create index'; export getParameterName from './getParameterName.js'; export isFlowFile from './isFlowFile.js'; export isFlowFileAnnotation from './isFlowFileAnnotation.js'; export iterateFunctionNodes from './iterateFunctionNodes.js'; export * as spacingFixers from './spacingFixers'; export quoteName from './quoteName'; export getTokenBeforeParens from './getTokenBeforeParens'; export getTokenAfterParens from './getTokenAfterParens'; eslint-plugin-flowtype-2.25.0/src/utilities/isFlowFile.js000066400000000000000000000004271300375303300234440ustar00rootroot00000000000000import isFlowFileAnnotation from './isFlowFileAnnotation.js'; export default (context) => { const comments = context.getAllComments(); if (!comments.length) { return false; } const firstComment = comments[0]; return isFlowFileAnnotation(firstComment.value); }; eslint-plugin-flowtype-2.25.0/src/utilities/isFlowFileAnnotation.js000066400000000000000000000007531300375303300255010ustar00rootroot00000000000000import _ from 'lodash'; const FLOW_MATCHER = /^@(?:no)?flow$/; export default (comment) => { // eslint-disable-next-line flowtype/require-valid-file-annotation // The flow parser splits comments with the following regex to look for the @flow flag. // See https://github.com/facebook/flow/blob/a96249b93541f2f7bfebd8d62085bf7a75de02f2/src/parsing/docblock.ml#L39 return _.some(comment.split(/[ \t\r\n\\*/]+/), (commentPart) => { return FLOW_MATCHER.test(commentPart); }); }; eslint-plugin-flowtype-2.25.0/src/utilities/iterateFunctionNodes.js000066400000000000000000000004731300375303300255360ustar00rootroot00000000000000export default (iterator) => { return (context, ...rest) => { const nodeIterator = iterator(context, ...rest); return { ArrowFunctionExpression: nodeIterator, FunctionDeclaration: nodeIterator, FunctionExpression: nodeIterator, FunctionTypeAnnotation: nodeIterator }; }; }; eslint-plugin-flowtype-2.25.0/src/utilities/quoteName.js000066400000000000000000000001061300375303300233310ustar00rootroot00000000000000export default (name) => { return name ? '"' + name + '" ' : ''; }; eslint-plugin-flowtype-2.25.0/src/utilities/spacingFixers.js000066400000000000000000000015671300375303300242140ustar00rootroot00000000000000export const stripSpacesBefore = (node, spaces) => { return (fixer) => { return fixer.removeRange([node.start - spaces, node.start]); }; }; export const stripSpacesAfter = (node, spaces) => { return (fixer) => { return fixer.removeRange([node.end, node.end + spaces]); }; }; export const addSpaceBefore = (node) => { return (fixer) => { return fixer.insertTextBefore(node, ' '); }; }; export const addSpaceAfter = (node) => { return (fixer) => { return fixer.insertTextAfter(node, ' '); }; }; export const stripSpaces = (direction, node, spaces) => { if (direction === 'before') { return stripSpacesBefore(node, spaces); } else { return stripSpacesAfter(node, spaces); } }; export const addSpace = (direction, node) => { if (direction === 'before') { return addSpaceBefore(node); } else { return addSpaceAfter(node); } }; eslint-plugin-flowtype-2.25.0/tests/000077500000000000000000000000001300375303300174005ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/tests/rules/000077500000000000000000000000001300375303300205325ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/tests/rules/assertions/000077500000000000000000000000001300375303300227245ustar00rootroot00000000000000eslint-plugin-flowtype-2.25.0/tests/rules/assertions/booleanStyle.js000066400000000000000000000012471300375303300257260ustar00rootroot00000000000000export default { invalid: [ { code: 'type X = bool', errors: [{message: 'Use "boolean", not "bool"'}], output: 'type X = boolean' }, { code: 'type X = bool', errors: [{message: 'Use "boolean", not "bool"'}], options: ['boolean'], output: 'type X = boolean' }, { code: 'type X = boolean', errors: [{message: 'Use "bool", not "boolean"'}], options: ['bool'], output: 'type X = bool' } ], valid: [ { code: 'type X = boolean' }, { code: 'type X = boolean', options: ['boolean'] }, { code: 'type X = bool', options: ['bool'] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/defineFlowType.js000066400000000000000000000101701300375303300262050ustar00rootroot00000000000000import { RuleTester } from 'eslint'; import noUndefRule from 'eslint/lib/rules/no-undef'; const VALID_WITH_DEFINE_FLOW_TYPE = [ { code: 'var a: AType', errors: [ '\'AType\' is not defined.' ] }, { code: 'var a: AType; var b: AType', errors: [ '\'AType\' is not defined.', '\'AType\' is not defined.' ] }, { code: 'var a; (a: AType)', errors: [ '\'AType\' is not defined.' ] }, { code: 'var a: AType', errors: [ '\'AType\' is not defined.', '\'BType\' is not defined.' ] }, { code: 'type A = AType', errors: [ '\'AType\' is not defined.' ] }, { code: 'function f(a: AType) {}', errors: [ '\'AType\' is not defined.' ] }, { code: 'function f(a: AType.a) {}', errors: [ '\'AType\' is not defined.' ] }, { code: 'function f(a: AType.a.b) {}', errors: [ '\'AType\' is not defined.' ] }, { code: 'function f(a): AType {}; var a: AType', errors: [ '\'AType\' is not defined.', '\'AType\' is not defined.' ] }, { code: 'function f(a): AType {}', errors: [ '\'AType\' is not defined.' ] }, { code: 'class C { a: AType }', errors: [ '\'AType\' is not defined.' ] }, { code: 'class C { a: AType.a }', errors: [ '\'AType\' is not defined.' ] }, { code: 'class C { a: AType.a.b }', errors: [ '\'AType\' is not defined.' ] }, { code: 'class C implements AType {}', errors: [ '\'AType\' is not defined.' ] }, { code: 'interface AType {}', errors: [ '\'AType\' is not defined.' ] }, { code: '({ a: ({b() {}}: AType) })', // `AType` appears twice in `globalScope.through` as distinct // references, this may be a babel-eslint bug. errors: [ '\'AType\' is not defined.', '\'AType\' is not defined.' ] }, { code: 'type X = {Y(): BType}', errors: [ '\'AType\' is not defined.', '\'BType\' is not defined.' ] }, { code: 'interface AType {}', errors: [ '\'AType\' is not defined.', '\'BType\' is not defined.' ] } ]; const ALWAYS_INVALID = [ { code: 'var a = b', errors: [ '\'b\' is not defined.' ] }, { code: 'function f(a = b) {}', errors: [ '\'b\' is not defined.' ] }, { code: 'class C extends b {}', errors: [ '\'b\' is not defined.' ] }, { code: 'class C { static S = b }', errors: [ '\'b\' is not defined.' ] } ]; const ALWAYS_VALID = [ 'var a: string', 'var a: Array', 'var a: Array', 'type A = Array', 'function f(a: string) {}', 'function f(a): string {}', 'class C { a: string }', 'var AType = {}; class C { a: AType.a }', 'declare module A { declare var a: AType }' ]; /** * This rule is tested differently than the rest because `RuleTester` is * designed to test rule reporting and define-flow-type doesn't report * anything. define-flow-type suppresses reports from no-undef. So we're * actually testing no-undef's reporting with define-flow-type enabled. */ { const ruleTester = new RuleTester({ parser: 'babel-eslint' }); ruleTester.run('no-under must not trigger an error in these cases', noUndefRule, { invalid: [], valid: ALWAYS_VALID }); } { const ruleTester = new RuleTester({ parser: 'babel-eslint' }); ruleTester.run('no-undef must trigger an error when define-flow-type is not used in these cases', noUndefRule, { invalid: [ ...ALWAYS_INVALID, ...VALID_WITH_DEFINE_FLOW_TYPE ], valid: [] }); } export default { invalid: [], valid: [ ...VALID_WITH_DEFINE_FLOW_TYPE.map((subject) => { return { code: subject.code, rules: { 'no-undef': 2 } }; }), ...VALID_WITH_DEFINE_FLOW_TYPE.map((subject) => { return { code: subject.code, rules: { 'no-undef': 2, 'no-use-before-define': [ 2, 'nofunc' ] } }; }) ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/delimiterDangle.js000066400000000000000000000335061300375303300263620ustar00rootroot00000000000000const OBJECT_TYPE_ANNOTATION = { invalid: [ { code: 'type X = { foo: string, }', errors: [{message: 'Unexpected trailing delimiter'}], output: 'type X = { foo: string }' }, { code: 'type X = { foo: string, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = { foo: string }' }, { code: 'type X = { foo: string; }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = { foo: string }' }, { code: 'type X = {\nfoo: string,\n}', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = {\nfoo: string\n}' }, { code: 'type X = { foo: string }', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = { foo: string, }' }, { code: 'type X = {\nfoo: string\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = {\nfoo: string,\n}' }, { code: 'type X = { foo: string, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['always-multiline'], output: 'type X = { foo: string }' }, { code: 'type X = {\nfoo: string\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always-multiline'], output: 'type X = {\nfoo: string,\n}' }, { code: 'type X = { foo: string; }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['only-multiline'], output: 'type X = { foo: string }' }, // Only indexers... { code: 'type X = { [key: string]: number, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = { [key: string]: number }' }, { code: 'type X = { [key: string]: number }', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = { [key: string]: number, }' }, { code: 'type X = { [key: string]: number, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['always-multiline'], output: 'type X = { [key: string]: number }' }, { code: 'type X = {\n[key: string]: number\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always-multiline'], output: 'type X = {\n[key: string]: number,\n}' }, { code: 'type X = { [key: string]: number; }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['only-multiline'], output: 'type X = { [key: string]: number }' }, // Indexer, Prop... { code: 'type X = { [key: string]: number, foo: string, }', errors: [{ // be sure it's reporting the prop, not the indexer column: 35, line: 1, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = { [key: string]: number, foo: string }' }, { code: 'type X = {\n[key: string]: number,\nfoo: string,\n}', errors: [{ // be sure it's reporting the prop, not the indexer column: 1, line: 3, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = {\n[key: string]: number,\nfoo: string\n}' }, { code: 'type X = {\n[key: string]: number,\naReallyLongPropertyNameHere: string,\n}', errors: [{ // be sure it's reporting the prop, not the indexer column: 1, line: 3, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = {\n[key: string]: number,\naReallyLongPropertyNameHere: string\n}' }, { code: 'type X = { [key: string]: number, foo: string }', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = { [key: string]: number, foo: string, }' }, { code: 'type X = {\n[key: string]: number;\nfoo: string\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = {\n[key: string]: number;\nfoo: string,\n}' }, { code: 'type X = { [key: string]: number, foo: string, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['always-multiline'], output: 'type X = { [key: string]: number, foo: string }' }, { code: 'type X = {\n[key: string]: number,\nfoo: string\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always-multiline'], output: 'type X = {\n[key: string]: number,\nfoo: string,\n}' }, { code: 'type X = { [key: string]: number, foo: string, }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['only-multiline'], output: 'type X = { [key: string]: number, foo: string }' }, // Prop, Indexer... { code: 'type X = { foo: string, [key: string]: number, }', errors: [{ // be sure it's reporting the indexer, not the prop column: 25, line: 1, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = { foo: string, [key: string]: number }' }, { code: 'type X = {\nfoo: string,\n[key: string]: number,\n}', errors: [{ // be sure it's reporting the prop, not the indexer column: 1, line: 3, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = {\nfoo: string,\n[key: string]: number\n}' }, { code: 'type X = {\naReallyLongPropertyNameHere: string,\n[key: string]: number,\n}', errors: [{ // be sure it's reporting the prop, not the indexer column: 1, line: 3, message: 'Unexpected trailing delimiter' }], options: ['never'], output: 'type X = {\naReallyLongPropertyNameHere: string,\n[key: string]: number\n}' }, { code: 'type X = { foo: string, [key: string]: number }', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = { foo: string, [key: string]: number, }' }, { code: 'type X = { foo: string; [key: string]: number }', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = { foo: string; [key: string]: number, }' }, { code: 'type X = { foo: string, [key: string]: number; }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['always-multiline'], output: 'type X = { foo: string, [key: string]: number }' }, { code: 'type X = {\nfoo: string,\n[key: string]: number\n}', errors: [{message: 'Missing trailing delimiter'}], options: ['always-multiline'], output: 'type X = {\nfoo: string,\n[key: string]: number,\n}' }, { code: 'type X = { foo: string, [key: string]: number; }', errors: [{message: 'Unexpected trailing delimiter'}], options: ['only-multiline'], output: 'type X = { foo: string, [key: string]: number }' } ], valid: [ { code: 'type X = { foo: string }' }, { code: 'type X = { foo: string }', options: ['never'] }, { code: 'type X = { foo: string, }', options: ['always'] }, { code: 'type X = { foo: string; }', options: ['always'] }, { code: 'type X = {\nfoo: string\n}', options: ['never'] }, { code: 'type X = {\nfoo: string,\n}', options: ['always'] }, { code: 'type X = { foo: string }', options: ['always-multiline'] }, { code: 'type X = {\nfoo: string,\n}', options: ['always-multiline'] }, { code: 'type X = {\nfoo: string;\n}', options: ['always-multiline'] }, { code: 'type X = { foo: string }', options: ['only-multiline'] }, { code: 'type X = {\nfoo: string\n}', options: ['only-multiline'] }, { code: 'type X = {\nfoo: string,\n}', options: ['only-multiline'] }, { code: 'type X = {\nfoo: string;\n}', options: ['only-multiline'] }, // Empty... { code: 'type X = {}', options: ['never'] }, { code: 'type X = {}', options: ['always'] }, { code: 'type X = {}', options: ['always-multiline'] }, { code: 'type X = {}', options: ['only-multiline'] }, // Only indexers... { code: 'type X = { [key: string]: number }', options: ['never'] }, { code: 'type X = { [key: string]: number, }', options: ['always'] }, { code: 'type X = { [key: string]: number; }', options: ['always'] }, { code: 'type X = { [key: string]: number }', options: ['always-multiline'] }, { code: 'type X = {\n[key: string]: number,\n}', options: ['always-multiline'] }, { code: 'type X = {\n[key: string]: number,\n}', options: ['only-multiline'] }, { code: 'type X = {\n[key: string]: number\n}', options: ['only-multiline'] }, { code: 'type X = { [key: string]: number }', options: ['only-multiline'] }, // Indexer, Prop... { code: 'type X = { [key: string]: number, foo: string }', options: ['never'] }, { code: 'type X = { [key: string]: number, foo: string, }', options: ['always'] }, { code: 'type X = { [key: string]: number; foo: string; }', options: ['always'] }, { code: 'type X = { [key: string]: number, foo: string }', options: ['always-multiline'] }, { code: 'type X = {\n[key: string]: number,\nfoo: string,\n}', options: ['always-multiline'] }, { code: 'type X = {\n[key: string]: number,\nfoo: string,\n}', options: ['only-multiline'] }, { code: 'type X = {\n[key: string]: number;\nfoo: string\n}', options: ['only-multiline'] }, { code: 'type X = { [key: string]: number, foo: string }', options: ['only-multiline'] }, // Prop, Indexer... { code: 'type X = { foo: string, [key: string]: number }', options: ['never'] }, { code: 'type X = { foo: string, [key: string]: number, }', options: ['always'] }, { code: 'type X = { foo: string; [key: string]: number; }', options: ['always'] }, { code: 'type X = { foo: string, [key: string]: number }', options: ['always-multiline'] }, { code: 'type X = {\nfoo: string,\n[key: string]: number,\n}', options: ['always-multiline'] }, { code: 'type X = {\nfoo: string,\n[key: string]: number,\n}', options: ['only-multiline'] }, { code: 'type X = {\nfoo: string;\n[key: string]: number\n}', options: ['only-multiline'] }, { code: 'type X = { foo: string, [key: string]: number }', options: ['only-multiline'] } ] }; const TUPLE_TYPE_ANNOTATION = { invalid: [ { code: 'type X = [string, number,]', errors: [{message: 'Unexpected trailing delimiter'}], output: 'type X = [string, number]' }, { code: 'type X = [string, number,]', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = [string, number]' }, { code: 'type X = [\nstring,\nnumber,\n]', errors: [{message: 'Unexpected trailing delimiter'}], options: ['never'], output: 'type X = [\nstring,\nnumber\n]' }, { code: 'type X = [string, number]', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = [string, number,]' }, { code: 'type X = [\nstring,\nnumber\n]', errors: [{message: 'Missing trailing delimiter'}], options: ['always'], output: 'type X = [\nstring,\nnumber,\n]' }, { code: 'type X = [string, number,]', errors: [{message: 'Unexpected trailing delimiter'}], options: ['always-multiline'], output: 'type X = [string, number]' }, { code: 'type X = [\nfoo, string\n]', errors: [{message: 'Missing trailing delimiter'}], options: ['always-multiline'], output: 'type X = [\nfoo, string,\n]' }, { code: 'type X = [ number, string, ]', errors: [{message: 'Unexpected trailing delimiter'}], options: ['only-multiline'], output: 'type X = [ number, string ]' } ], valid: [ { code: 'type X = [string, number]' }, { code: 'type X = [string, number]', options: ['never'] }, { code: 'type X = [\nstring,\nnumber\n]', options: ['never'] }, { code: 'type X = [string, number,]', options: ['always'] }, { code: 'type X = [\nstring,\nnumber,\n]', options: ['always'] }, { code: 'type X = [ foo, string ]', options: ['always-multiline'] }, { code: 'type X = [\nfoo, string,\n]', options: ['always-multiline'] }, { code: 'type X = [ number, string ]', options: ['only-multiline'] }, { code: 'type X = [\nnumber,\nstring\n]', options: ['only-multiline'] }, { code: 'type X = [\nnumber,\nstring,\n]', options: ['only-multiline'] }, { code: 'type X = []', options: ['never'] }, { code: 'type X = []', options: ['always'] }, { code: 'type X = []', options: ['always-multiline'] }, { code: 'type X = []', options: ['only-multiline'] } ] }; export default { invalid: [ ...OBJECT_TYPE_ANNOTATION.invalid, ...TUPLE_TYPE_ANNOTATION.invalid ], valid: [ ...OBJECT_TYPE_ANNOTATION.valid, ...TUPLE_TYPE_ANNOTATION.valid ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/genericSpacing.js000066400000000000000000000073751300375303300262170ustar00rootroot00000000000000export default { invalid: [ // Never { code: 'type X = Promise< string>', errors: [{message: 'There must be no space at start of "Promise" generic type annotation'}], output: 'type X = Promise' }, { code: 'type X = Promise< string>', errors: [{message: 'There must be no space at start of "Promise" generic type annotation'}], options: ['never'], output: 'type X = Promise' }, { code: 'type X = FooBar', errors: [{message: 'There must be no space at end of "FooBar" generic type annotation'}], output: 'type X = FooBar' }, { code: 'type X = Promise< string >', errors: [ {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'} ], output: 'type X = Promise' }, { code: 'type X = Promise< (foo), bar, (((baz))) >', errors: [ {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'} ], output: 'type X = Promise<(foo), bar, (((baz)))>' }, // Always (given no space) { code: 'type X = Promise', errors: [{message: 'There must be a space at start of "Promise" generic type annotation'}], options: ['always'], output: 'type X = Promise< string >' }, { code: 'type X = FooBar< string>', errors: [{message: 'There must be a space at end of "FooBar" generic type annotation'}], options: ['always'], output: 'type X = FooBar< string >' }, { code: 'type X = Promise', errors: [ {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'], output: 'type X = Promise< string >' }, { code: 'type X = Promise<(foo), bar, (((baz)))>', errors: [ {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'], output: 'type X = Promise< (foo), bar, (((baz))) >' }, // Always (given too many spaces) { code: 'type X = FooBar< string >', errors: [{message: 'There must be one space at start of "FooBar" generic type annotation'}], options: ['always'], output: 'type X = FooBar< string >' }, { code: 'type X = FooBar< string >', errors: [{message: 'There must be one space at end of "FooBar" generic type annotation'}], options: ['always'], output: 'type X = FooBar< string >' }, { code: 'type X = Promise< (foo), bar, (((baz))) >', errors: [ {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'} ], options: ['always'], output: 'type X = Promise< (foo), bar, (((baz))) >' } ], valid: [ // Never {code: 'type X = Promise'}, {code: 'type X = Promise<(string)>'}, {code: 'type X = Promise<(foo), bar, (((baz)))>'}, // Always { code: 'type X = Promise< string >', options: ['always'] }, { code: 'type X = Promise< (string) >', options: ['always'] }, { code: 'type X = Promise< (foo), bar, (((baz))) >', options: ['always'] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/noDupeKeys.js000066400000000000000000000006011300375303300253450ustar00rootroot00000000000000export default { invalid: [ { code: 'type FooType = { a: number, b: string, a: number }', errors: [{message: 'Duplicate property.'}] }, { code: 'type FooType = { a: number, b: string, a: string }', errors: [{message: 'Duplicate property.'}] } ], valid: [ { code: 'type FooType = { a: number, b: string, c: number }' } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/noWeakTypes.js000066400000000000000000000125751300375303300255450ustar00rootroot00000000000000export default { invalid: [ { code: 'function foo(thing): any {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'function foo(thing): Promise {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'function foo(thing): Promise> {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'function foo(thing): Object {}', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'function foo(thing): Promise {}', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'function foo(thing): Promise> {}', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'function foo(thing): Function {}', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: 'function foo(thing): Promise {}', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: 'function foo(thing): Promise> {}', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: '(foo: any) => {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: '(foo: Function) => {}', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: '(foo?: any) => {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: '(foo?: Function) => {}', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: '(foo: { a: any }) => {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: '(foo: { a: Object }) => {}', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: '(foo: any[]) => {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'type Foo = any', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'type Foo = Function', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: 'type Foo = { a: any }', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'type Foo = { a: Object }', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'type Foo = { (a: Object): string }', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'type Foo = { (a: string): Function }', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: 'function foo(thing: any) {}', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'function foo(thing: Object) {}', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'var foo: Function', errors: [{ message: 'Unexpected use of weak type "Function"' }] }, { code: 'var foo: Object', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'class Foo { props: any }', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'class Foo { props: Object }', errors: [{ message: 'Unexpected use of weak type "Object"' }] }, { code: 'var foo: any', errors: [{ message: 'Unexpected use of weak type "any"' }] }, { code: 'type X = any; type Y = Function; type Z = Object', errors: [ {message: 'Unexpected use of weak type "any"'}, {message: 'Unexpected use of weak type "Object"'} ], options: [{ Function: false }] }, { code: 'type X = any; type Y = Function; type Z = Object', errors: [{message: 'Unexpected use of weak type "Function"'}], options: [{ Object: false, any: false }] } ], valid: [ { code: 'function foo(thing): string {}' }, { code: 'function foo(thing): Promise {}' }, { code: 'function foo(thing): Promise> {}' }, { code: '(foo?: string) => {}' }, { code: '(foo: ?string) => {}' }, { code: '(foo: { a: string }) => {}' }, { code: '(foo: { a: ?string }) => {}' }, { code: '(foo: string[]) => {}' }, { code: 'type Foo = string' }, { code: 'type Foo = { a: string }' }, { code: 'type Foo = { (a: string): string }' }, { code: 'function foo(thing: string) {}' }, { code: 'var foo: string' }, { code: 'class Foo { props: string }' }, { code: 'type X = any; type Y = Object', options: [{ Object: false, any: false }] }, { code: 'type X = Function', options: [{Function: false}] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/objectTypeDelimiter.js000066400000000000000000000106221300375303300272320ustar00rootroot00000000000000export default { invalid: [ { code: 'type Foo = { a: Foo, b: Bar }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'type Foo = { a: Foo; b: Bar }' }, { code: 'type Foo = { a: Foo; b: Bar }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'type Foo = { a: Foo, b: Bar }' }, { code: 'type Foo = { [a: string]: Foo, [b: string]: Bar }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'type Foo = { [a: string]: Foo; [b: string]: Bar }' }, { code: 'type Foo = { [a: string]: Foo; [b: string]: Bar }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'type Foo = { [a: string]: Foo, [b: string]: Bar }' }, { code: 'type Foo = { (): Foo, (): Bar }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'type Foo = { (): Foo; (): Bar }' }, { code: 'type Foo = { (): Foo; (): Bar }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'type Foo = { (): Foo, (): Bar }' }, { code: 'declare class Foo { a: Foo, }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'declare class Foo { a: Foo; }' }, { code: 'declare class Foo { a: Foo; }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'declare class Foo { a: Foo, }' }, { code: 'declare class Foo { [a: string]: Foo, }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'declare class Foo { [a: string]: Foo; }' }, { code: 'declare class Foo { a: Foo; }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'declare class Foo { a: Foo, }' }, { code: 'declare class Foo { (): Foo, }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'declare class Foo { (): Foo; }' }, { code: 'declare class Foo { (): Foo; }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'declare class Foo { (): Foo, }' }, { code: 'declare class Foo { static (): Foo, }', errors: [{message: 'Prefer semicolons to commas in object and class types'}], options: ['semicolon'], output: 'declare class Foo { static (): Foo; }' }, { code: 'declare class Foo { static (): Foo; }', errors: [{message: 'Prefer commas to semicolons in object and class types'}], options: ['comma'], output: 'declare class Foo { static (): Foo, }' } ], valid: [ { code: 'type Foo = { a: Foo; b: Bar }', options: ['semicolon'] }, { code: 'type Foo = { a: Foo, b: Bar }', options: ['comma'] }, { code: 'type Foo = { [a: string]: Foo; [b: string]: Bar }', options: ['semicolon'] }, { code: 'type Foo = { [a: string]: Foo, [b: string]: Bar }', options: ['comma'] }, { code: 'type Foo = { (): Foo; (): Bar }', options: ['semicolon'] }, { code: 'type Foo = { (): Foo, (): Bar }', options: ['comma'] }, { code: 'type Foo = { a: Foo, b: Bar }' }, { code: 'type Foo = { [a: string]: Foo, [b: string]: Bar }' }, { code: 'type Foo = { (): Foo, (): Bar }' }, { code: 'declare class Foo { a: Foo; }', options: ['semicolon'] }, { code: 'declare class Foo { a: Foo, }', options: ['comma'] }, { code: 'declare class Foo { [a: string]: Foo; }', options: ['semicolon'] }, { code: 'declare class Foo { [a: string]: Foo, }', options: ['comma'] }, { code: 'declare class Foo { (): Foo; }', options: ['semicolon'] }, { code: 'declare class Foo { (): Foo, }', options: ['comma'] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/requireParameterType.js000066400000000000000000000067031300375303300274470ustar00rootroot00000000000000export default { invalid: [ { code: '(foo) => {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ] }, { code: 'function x(foo) {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ] }, { code: 'function x(foo) {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ], options: [ { excludeArrowFunctions: true } ] }, { code: '(foo = \'FOO\') => {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ] }, { code: '(...foo) => {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ] }, { code: '({foo}) => {}', errors: [ { message: 'Missing "{foo}" parameter type annotation.' } ] }, { code: '([foo]) => {}', errors: [ { message: 'Missing "[foo]" parameter type annotation.' } ] }, { code: '({foo = 1} = {}) => {}', errors: [ { message: 'Missing "{foo = 1}" parameter type annotation.' } ] }, { code: '// @flow\n(foo) => {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: '(foo) => {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ], options: [ { excludeArrowFunctions: 'expressionsOnly' } ] }, { code: 'function x(foo) {}', errors: [ { message: 'Missing "foo" parameter type annotation.' } ], options: [ { excludeArrowFunctions: 'expressionsOnly' } ] }, { code: '(_foo: number, bar) => {}', errors: [ { message: 'Missing "bar" parameter type annotation.' } ], options: [ { excludeParameterMatch: '^_' } ] }, { code: '(_foo, bar) => {}', errors: [ { message: 'Missing "bar" parameter type annotation.' } ], options: [ { excludeParameterMatch: '^_' } ] } ], valid: [ { code: '(foo: string) => {}' }, { code: '(foo: string = \'FOO\') => {}' }, { code: '(...foo: string) => {}' }, { code: '({foo}: {foo: string}) => {}' }, { code: '([foo]: Array) => {}' }, { code: '(foo) => {}', settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: '(foo) => {}', options: [ { excludeArrowFunctions: true } ] }, { code: '(foo) => 3', options: [ { excludeArrowFunctions: 'expressionsOnly' } ] }, { code: '(_foo, bar: string) => {}', options: [ { excludeParameterMatch: '^_' } ] }, { code: '(_foo: number, bar: string) => {}', options: [ { excludeParameterMatch: '^_' } ] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/requireReturnType.js000066400000000000000000000207351300375303300270070ustar00rootroot00000000000000export default { invalid: [ { code: '(foo) => { return "foo"; }', errors: [ { message: 'Missing return type annotation.' } ] }, { code: '(foo) => { return "foo"; }', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always' ] }, { code: '(foo) => "foo"', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always' ] }, { code: '(foo) => ({})', errors: [ { message: 'Missing return type annotation.' } ] }, { code: '(foo): undefined => { return; }', errors: [ { message: 'Must not annotate undefined return type.' } ] }, { code: '(foo): void => { return; }', errors: [ { message: 'Must not annotate undefined return type.' } ] }, { code: '(foo): undefined => { return undefined; }', errors: [ { message: 'Must not annotate undefined return type.' } ] }, { code: '(foo): void => { return void 0; }', errors: [ { message: 'Must not annotate undefined return type.' } ] }, { code: '(foo): undefined => { return; }', errors: [ { message: 'Must not annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo): void => { return; }', errors: [ { message: 'Must not annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo) => { return; }', errors: [ { message: 'Must annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo): undefined => { return undefined; }', errors: [ { message: 'Must not annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo) => { return undefined; }', errors: [ { message: 'Must annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo) => { return void 0; }', errors: [ { message: 'Must annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '// @flow\n(foo) => { return 1; }', errors: [ { message: 'Missing return type annotation.' } ], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: '// @flow\n (foo) => { return undefined; }', errors: [ { message: 'Must annotate undefined return type.' } ], options: [ 'always', { annotateUndefined: 'always' } ], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: 'async () => { return 2; }', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always' ] }, { code: 'async () => {}', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always', { annotateUndefined: 'always' } ] }, { code: 'async function x() {}', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always', { annotateUndefined: 'always' } ] }, { code: 'async () => { return; }', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always' ] }, { code: 'function* x() {}', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always' ] }, { code: '() => { return 3; }', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always', { excludeArrowFunctions: 'expressionsOnly' } ] }, { code: 'async () => { return 4; }', errors: [ { message: 'Missing return type annotation.' } ], options: [ 'always', { excludeArrowFunctions: 'expressionsOnly' } ] } ], valid: [ { code: '(foo): string => {}' }, { code: '(foo): string => {}', options: [ 'always' ] }, { code: '(foo) => { return; }' }, { code: '(foo): Object => ( {} )' }, { code: '(foo) => { return undefined; }' }, { code: '(foo) => { return void 0; }' }, { code: '(foo): undefined => { return; }', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo): void => { return; }', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo) => { return; }', options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo) => { return undefined; }', options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo) => { return void 0; }', options: [ 'always', { annotateUndefined: 'never' } ] }, { code: '(foo): undefined => { return undefined; }', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo): void => { return void 0; }', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: '(foo) => { return 1; }', options: [ 'always' ], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: '(foo) => { return undefined; }', options: [ 'always', { annotateUndefined: 'always' } ], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: 'async function doThing(): Promise {}', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: 'function* doThing(): Generator { yield 2; }', options: [ 'always', { annotateUndefined: 'always' } ] }, { code: 'async (foo): Promise => { return 3; }' }, { code: '() => 3', options: [ 'always', { excludeArrowFunctions: true } ] }, { code: '() => { return 4; }', options: [ 'always', { excludeArrowFunctions: true } ] }, { code: '() => undefined', options: [ 'always', { excludeArrowFunctions: true } ] }, { code: '() => undefined', options: [ 'always', { annotateUndefined: 'always', excludeArrowFunctions: true } ] }, { code: '() => { return undefined; }', options: [ 'always', { annotateUndefined: 'always', excludeArrowFunctions: true } ] }, { code: '() => 3', options: [ 'always', { excludeArrowFunctions: 'expressionsOnly' } ] }, { code: 'async () => 3', options: [ 'always', { excludeArrowFunctions: 'expressionsOnly' } ] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/requireValidFileAnnotation.js000066400000000000000000000044531300375303300305570ustar00rootroot00000000000000export default { invalid: [ { code: ';// @flow', errors: [ { message: 'Flow file annotation not at the top of the file.' } ] }, { code: ';\n// @flow', errors: [ { message: 'Flow file annotation not at the top of the file.' } ] }, { code: '// @Flow', errors: [ { message: 'Malformed flow file annotation.' } ] }, { code: '// @floweeeeeee', errors: [ { message: 'Malformed flow file annotation.' } ] }, { code: '// @NoFlow', errors: [ { message: 'Malformed flow file annotation.' } ] }, { code: '// @nofloweeeeeee', errors: [ { message: 'Malformed flow file annotation.' } ] }, { code: 'a;', errors: [ { message: 'Flow file annotation is missing.' } ], options: [ 'always' ] }, { code: '/* @flow */', errors: [ { message: 'Flow file annotation style must be `// @flow`' } ], options: [ 'always', { annotationStyle: 'line' } ] }, { code: '// @flow', errors: [ { message: 'Flow file annotation style must be `/* @flow */`' } ], options: [ 'always', { annotationStyle: 'block' } ] } ], valid: [ { code: 'a;' }, { code: '// @flow\na;' }, { code: '//@flow\na;' }, { code: '//**@flow\na;' }, { code: '/* foo @flow bar */\na;' }, { code: '\n\n// @flow\na;' }, { code: '// @flow\n// @FLow' }, { code: '// @noflow\na;' }, { code: 'a;', options: ['always'], settings: { flowtype: { onlyFilesWithFlowAnnotation: true } } }, { code: '// @flow', options: [ 'always', { annotationStyle: 'line' } ] }, { code: '/* @flow */', options: [ 'always', { annotationStyle: 'block' } ] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/semi.js000066400000000000000000000017571300375303300242310ustar00rootroot00000000000000export default { invalid: [ { code: 'type FooType = {}', errors: [ { message: 'Missing semicolon.' } ], options: [], output: 'type FooType = {};' }, { code: 'type FooType = {}', errors: [ { message: 'Missing semicolon.' } ], options: ['always'], output: 'type FooType = {};' }, { code: 'type FooType = {};', errors: [ { message: 'Extra semicolon.' } ], options: ['never'], output: 'type FooType = {}' } ], valid: [ { code: 'type FooType = {};' }, { code: 'type FooType = {};', options: ['always'] }, { code: 'type FooType = { a: number;\n b: string;\n };', options: ['always'] }, { code: 'type FooType = { a: number;\n b: string;\n }', options: ['never'] }, { code: 'type FooType = {}', options: ['never'] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/sortKeys.js000066400000000000000000000056571300375303300251220ustar00rootroot00000000000000export default { invalid: [ { code: 'type FooType = { a: number, c: number, b: string }', errors: [{message: 'Expected type annotations to be in ascending order. "b" should be before "c".'}] }, { code: 'type FooType = { a: number, b: number, C: number }', errors: [{message: 'Expected type annotations to be in ascending order. "C" should be before "b".'}] }, { code: 'type FooType = { 1: number, 2: number, 10: number }', errors: [{message: 'Expected type annotations to be in ascending order. "10" should be before "2".'}] }, { code: 'type FooType = { a: number, b: number }', errors: [{message: 'Expected type annotations to be in descending order. "b" should be before "a".'}], options: ['desc'] }, { code: 'type FooType = { C: number, b: number, a: string }', errors: [{message: 'Expected type annotations to be in descending order. "b" should be before "C".'}], options: ['desc'] }, { code: 'type FooType = { 10: number, 2: number, 1: number }', errors: [{message: 'Expected type annotations to be in descending order. "2" should be before "10".'}], options: ['desc'] }, { code: 'type FooType = { a: number, c: number, C: number, b: string }', errors: [{message: 'Expected type annotations to be in insensitive ascending order. "b" should be before "C".'}], options: ['asc', {caseSensitive: false}] }, { code: 'type FooType = { a: number, C: number, c: number, b: string }', errors: [{message: 'Expected type annotations to be in insensitive ascending order. "b" should be before "c".'}], options: ['asc', {caseSensitive: false}] }, { code: 'type FooType = { 1: number, 10: number, 2: boolean }', errors: [{message: 'Expected type annotations to be in natural ascending order. "2" should be before "10".'}], options: ['asc', {natural: true}] } ], valid: [ { code: 'type FooType = { a: number }' }, { code: 'type FooType = { a: number, b: number, c: (boolean | number) }' }, { code: 'type FooType = { C: number, a: string, b: foo }' }, { code: 'type FooType = { 1: number, 10: number, 2: boolean }' }, { code: 'type FooType = { c: number, b: number, a: number }', options: ['desc'] }, { code: 'type FooType = { b: string, a: {}, C: number }', options: ['desc'] }, { code: 'type FooType = { 2: number, 10: number, 1: boolean }', options: ['desc'] }, { code: 'type FooType = { a: number, b: number, c: number, C: number }', options: ['asc', {caseSensitive: false}] }, { code: 'type FooType = { a: number, b: number, C: number, c: number }', options: ['asc', {caseSensitive: false}] }, { code: 'type FooType = { 1:number, 2: number, 10: number }', options: ['asc', {natural: true}] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/spaceAfterTypeColon.js000066400000000000000000000716461300375303300272120ustar00rootroot00000000000000import _ from 'lodash'; const ARROW_FUNCTION_PARAMS = { invalid: [ { code: '(foo: string) => {}', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: '(foo:string) => {}' }, { code: '(foo: string) => {}', errors: [{message: 'There must be 1 space after "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo: string) => {}' }, { code: '(foo:(() => void)) => {}', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo: (() => void)) => {}' }, { code: '(foo: (() => void)) => {}', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: '(foo:(() => void)) => {}' }, { code: '(foo: (() => void)) => {}', errors: [{message: 'There must be 1 space after "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo: (() => void)) => {}' }, { code: '({ lorem, ipsum, dolor } : SomeType) => {}', errors: [{message: 'There must be 1 space after "{ lorem, ipsum, dolor }" parameter type annotation colon.'}], output: '({ lorem, ipsum, dolor } : SomeType) => {}' }, { code: '(foo:{ a: string, b: number }) => {}', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: '(foo: { a: string, b: number }) => {}' }, { code: '({ a, b } :{ a: string, b: number }) => {}', errors: [{message: 'There must be a space after "{ a, b }" parameter type annotation colon.'}], output: '({ a, b } : { a: string, b: number }) => {}' }, { code: '([ a, b ] :string[]) => {}', errors: [{message: 'There must be a space after "[ a, b ]" parameter type annotation colon.'}], output: '([ a, b ] : string[]) => {}' }, { code: '(i?:number) => {}', errors: [{message: 'There must be a space after "i" parameter type annotation colon.'}], output: '(i?: number) => {}' }, { code: '(i?: number) => {}', errors: [{message: 'There must be 1 space after "i" parameter type annotation colon.'}], output: '(i?: number) => {}' }, { code: '(i?: number) => {}', errors: [{message: 'There must be no space after "i" parameter type annotation colon.'}], options: ['never'], output: '(i?:number) => {}' } ], valid: [ { code: '(foo) => {}' }, { code: '(foo: string) => {}' }, { code: '(foo: (string|number)) => {}' }, { code: '(foo:string) => {}', options: ['never'] }, { code: '(foo: string) => {}', options: ['always'] }, { code: '(foo:(() => void)) => {}', options: ['never'] }, { code: '(foo: (() => void)) => {}', options: ['always'] }, { code: '({ lorem, ipsum, dolor }: SomeType) => {}' }, { code: '(foo: { a: string, b: number }) => {}' }, { code: '({ a, b }: ?{ a: string, b: number }) => {}' }, { code: '([ a, b ]: string[]) => {}' }, { code: '(i?: number) => {}' }, { code: '(i?:number) => {}', options: ['never'] } ] }; const ARROW_FUNCTION_RETURN = { invalid: [ { code: '():Object => {}', errors: [{message: 'There must be a space after return type colon.'}], options: ['always'], output: '(): Object => {}' }, { code: '(): Object => {}', errors: [{message: 'There must be no space after return type colon.'}], options: ['never'], output: '():Object => {}' }, { code: '(): Object => {}', errors: [{message: 'There must be 1 space after return type colon.'}], options: ['always'], output: '(): Object => {}' }, { code: '():(() => void) => {}', errors: [{message: 'There must be a space after return type colon.'}], options: ['always'], output: '(): (() => void) => {}' }, { code: '(): (() => void) => {}', errors: [{message: 'There must be no space after return type colon.'}], options: ['never'], output: '():(() => void) => {}' }, { code: '(): (() => void) => {}', errors: [{message: 'There must be 1 space after return type colon.'}], options: ['always'], output: '(): (() => void) => {}' } ], valid: [ { code: '():Object => {}', options: ['never'] }, { code: '(): Object => {}', options: ['always'] }, { code: '():(number | string) => {}', options: ['never'] }, { code: '(): (number | string) => {}', options: ['always'] }, { code: '():number|string => {}', options: ['never'] }, { code: '(): number|string => {}', options: ['always'] }, { code: '():(() => void) => {}', options: ['never'] }, { code: '(): (() => void) => {}', options: ['always'] }, { code: '():( () => void ) => {}', options: ['never'] }, { code: '(): ( () => void ) => {}', options: ['always'] }, { code: '(): { a: number, b: string } => {}' }, { code: '() :{ a:number, b:string } => {}', options: ['never'] } ] }; const FUNCTION_PARAMS = { invalid: [ { code: 'export default function (foo: string) {}', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: 'export default function (foo:string) {}' }, { code: 'function foo (foo: string) {}', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: 'function foo (foo:string) {}' }, { code: '(foo:string) => {}', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo: string) => {}' }, { code: 'function foo (foo:string) {}', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'function foo (foo: string) {}' }, { code: 'async function foo({ lorem, ipsum, dolor }:SomeType) {}', errors: [{message: 'There must be a space after "{ lorem, ipsum, dolor }" parameter type annotation colon.'}], output: 'async function foo({ lorem, ipsum, dolor }: SomeType) {}' }, { code: 'function x(i?:number) {}', errors: [{message: 'There must be a space after "i" parameter type annotation colon.'}], output: 'function x(i?: number) {}' }, { code: 'function x(i?: number) {}', errors: [{message: 'There must be 1 space after "i" parameter type annotation colon.'}], output: 'function x(i?: number) {}' }, { code: 'function x(i?: number) {}', errors: [{message: 'There must be no space after "i" parameter type annotation colon.'}], options: ['never'], output: 'function x(i?:number) {}' } ], valid: [ { code: 'function x(foo: string) {}' }, { code: 'class Foo { constructor(foo: string) {} }' }, { code: 'function x(foo:string) {}', options: ['never'] }, { code: 'class Foo { constructor(foo:string) {} }', options: ['never'] }, { code: 'async function foo({ lorem, ipsum, dolor }: SomeType) {}' }, { code: 'function x({ a, b }: { a: string, b: number }) {}' }, { code: 'function x(i?: number) {}' }, { code: 'function x(i?:number) {}', options: ['never'] } ] }; const FUNCTION_RETURN = { invalid: [ { code: 'function a():x {}', errors: [{message: 'There must be a space after return type colon.'}], output: 'function a(): x {}' }, { code: 'function a(): x {}', errors: [{message: 'There must be 1 space after return type colon.'}], options: ['always'], output: 'function a(): x {}' }, { code: 'function a(): x {}', errors: [{message: 'There must be no space after return type colon.'}], options: ['never'], output: 'function a():x {}' } ], valid: [ { code: 'function a(): x {}' }, { code: 'function a():x {}', options: ['never'] }, { code: 'function a(): (number | string) {}' }, { code: 'function a() :(number | string) {}', options: ['never'] } ] }; const FUNCTION_TYPE_PARAMS = { invalid: [ { code: 'type X = (foo:number) => string', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: number) => string' }, { code: 'type X = (foo: number) => string', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: 'type X = (foo:number) => string' }, { code: 'type X = (foo: number) => string', errors: [{message: 'There must be 1 space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: number) => string' }, { code: 'type X = (foo:?number) => string', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: ?number) => string' }, { code: 'type X = (foo:(number)) => string', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: (number)) => string' }, { code: 'type X = (foo:((number))) => string', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: ((number))) => string' }, { code: 'type X = (foo: ((number))) => string', errors: [{message: 'There must be 1 space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: ((number))) => string' }, { code: 'type X = (foo: ((number))) => string', errors: [{message: 'There must be no space after "foo" parameter type annotation colon.'}], options: ['never'], output: 'type X = (foo:((number))) => string' }, { code: 'type X = (foo:?(number)) => string', errors: [{message: 'There must be a space after "foo" parameter type annotation colon.'}], output: 'type X = (foo: ?(number)) => string' }, { code: 'type TArrayPredicate = (el: T, i?:number) => boolean', errors: [{message: 'There must be a space after "i" parameter type annotation colon.'}], output: 'type TArrayPredicate = (el: T, i?: number) => boolean' }, { code: 'type TArrayPredicate = (el: T, i?: number) => boolean', errors: [{message: 'There must be 1 space after "i" parameter type annotation colon.'}], output: 'type TArrayPredicate = (el: T, i?: number) => boolean' }, { code: 'type TArrayPredicate = (el:T, i?: number) => boolean', errors: [{message: 'There must be no space after "i" parameter type annotation colon.'}], options: ['never'], output: 'type TArrayPredicate = (el:T, i?:number) => boolean' } ], valid: [ { code: 'type X = (foo: number) => string;' }, { code: 'type X = (foo : number) => string;' }, { code: 'type X = (foo: ?number) => string;' }, { code: 'type X = (foo? : ?number) => string;' }, { code: 'type X = (foo: ?{ x: number }) => string;' }, { code: 'type X = (foo:number) => string;', options: ['never'] }, { code: 'type X = (foo:?{ x:number }) => string;', options: ['never'] }, { code: 'type X = (foo: (number)) => string' }, { code: 'type X = (foo: ((number))) => string' }, { code: 'type X = (foo:((number))) => string', options: ['never'] }, { code: 'type X = ?(foo: ((number))) => string' }, { code: 'type X = ?(foo:((number))) => string', options: ['never'] }, { code: 'type TArrayPredicate = (el: T, i?: number) => boolean' }, { code: 'type TArrayPredicate = (el:T, i?:number) => boolean', options: ['never'] } ] }; const CLASS_PROPERTIES = { invalid: [ { code: 'class X { foo:string }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { foo: string }' }, { code: 'class X { foo: string }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { foo:string }' }, { code: 'class X { foo:?string }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { foo: ?string }' }, { code: 'class X { foo: ?string }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { foo:?string }' }, { code: 'class X { static foo:number }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { static foo: number }' }, { code: 'class X { static foo: number }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { static foo:number }' }, { code: 'class X { static foo :number }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { static foo : number }' }, { code: 'class X { static foo : number }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { static foo :number }' }, { code: 'declare class X { static foo:number }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'declare class X { static foo: number }' }, { code: 'declare class X { static foo: number }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'declare class X { static foo:number }' }, { code: 'declare class X { static foo :number }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'declare class X { static foo : number }' }, { code: 'declare class X { static foo : number }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'declare class X { static foo :number }' }, { code: 'class X { +foo:string }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { +foo: string }' }, { code: 'class X { +foo: string }', errors: [{message: 'There must be 1 space after "foo" class property type annotation colon.'}], output: 'class X { +foo: string }' }, { code: 'class X { +foo: string }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { +foo:string }' }, { code: 'class X { static +foo:string }', errors: [{message: 'There must be a space after "foo" class property type annotation colon.'}], output: 'class X { static +foo: string }' }, { code: 'class X { static +foo: string }', errors: [{message: 'There must be 1 space after "foo" class property type annotation colon.'}], output: 'class X { static +foo: string }' }, { code: 'class X { static +foo: string }', errors: [{message: 'There must be no space after "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { static +foo:string }' } ], valid: [ { code: 'class Foo { bar }' }, { code: 'class Foo { bar = 3 }' }, { code: 'class Foo { bar: string }' }, { code: 'class Foo { bar: ?string }' }, { code: 'class Foo { bar:string }', options: ['never'] }, { code: 'class Foo { bar:?string }', options: ['never'] }, { code: 'class X { static foo : number }' }, { code: 'class X { static foo :number }', options: ['never'] }, { code: 'declare class X { static foo : number }' }, { code: 'declare class X { static foo :number }', options: ['never'] }, { code: 'class X { +foo: string }' }, { code: 'class X { static +foo: string }' }, { code: 'class X { +foo:string }', options: ['never'] }, { code: 'class X { static +foo:string }', options: ['never'] } ] }; const OBJECT_TYPE_PROPERTIES = { invalid: [ { code: 'type X = { foo:string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'type X = { foo: string }' }, { code: 'type X = { foo:string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo: string }' }, { code: 'type X = { foo: string }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'type X = { foo:string }' }, { code: 'type X = { foo: string }', errors: [{message: 'There must be 1 space after "foo" type annotation colon.'}], output: 'type X = { foo: string }' }, { code: 'type X = { foo?:string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'type X = { foo?: string }' }, { code: 'type X = { foo?: string }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'type X = { foo?:string }' }, { code: 'type X = { foo?:?string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'type X = { foo?: ?string }' }, { code: 'type X = { foo?: ?string }', errors: [{message: 'There must be 1 space after "foo" type annotation colon.'}], output: 'type X = { foo?: ?string }' }, { code: 'type Foo = { barType:(string | () => void) }', errors: [{message: 'There must be a space after "barType" type annotation colon.'}], output: 'type Foo = { barType: (string | () => void) }' }, { code: 'type Foo = { barType:(((string | () => void))) }', errors: [{message: 'There must be a space after "barType" type annotation colon.'}], output: 'type Foo = { barType: (((string | () => void))) }' }, { code: 'type Foo = { barType: (string | () => void) }', errors: [{message: 'There must be no space after "barType" type annotation colon.'}], options: ['never'], output: 'type Foo = { barType:(string | () => void) }' }, { code: 'type Foo = { barType: (string | () => void) }', errors: [{message: 'There must be 1 space after "barType" type annotation colon.'}], output: 'type Foo = { barType: (string | () => void) }' }, { code: 'type Foo = { barType: ((string | () => void)) }', errors: [{message: 'There must be 1 space after "barType" type annotation colon.'}], output: 'type Foo = { barType: ((string | () => void)) }' }, { code: 'type X = { get:() => A; }', errors: [{message: 'There must be a space after "get" type annotation colon.'}], output: 'type X = { get: () => A; }' }, { code: 'type X = { get:() => A; }', errors: [{message: 'There must be a space after "get" type annotation colon.'}], output: 'type X = { get: () => A; }' }, { code: 'type X = { get: () => A; }', errors: [{message: 'There must be no space after "get" type annotation colon.'}], options: ['never'], output: 'type X = { get:() => A; }' }, { code: 'type X = { get: () => A; }', errors: [{message: 'There must be no space after "get" type annotation colon.'}], options: ['never'], output: 'type X = { get:() => A; }' }, { code: 'type X = { get: () => A; }', errors: [{message: 'There must be 1 space after "get" type annotation colon.'}], output: 'type X = { get: () => A; }' }, { code: 'type X = { get: () => A; }', errors: [{message: 'There must be 1 space after "get" type annotation colon.'}], output: 'type X = { get: () => A; }' }, { code: 'type X = { +foo:string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'type X = { +foo: string }' }, { code: 'type X = { +foo: string }', errors: [{message: 'There must be 1 space after "foo" type annotation colon.'}], output: 'type X = { +foo: string }' }, { code: 'type X = { +foo: string }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'type X = { +foo:string }' }, { code: 'type X = { +foo?:string }', errors: [{message: 'There must be a space after "foo" type annotation colon.'}], output: 'type X = { +foo?: string }' }, { code: 'type X = { +foo?: string }', errors: [{message: 'There must be 1 space after "foo" type annotation colon.'}], output: 'type X = { +foo?: string }' }, { code: 'type X = { +foo?: string }', errors: [{message: 'There must be no space after "foo" type annotation colon.'}], options: ['never'], output: 'type X = { +foo?:string }' } ], valid: [ { code: 'type X = { foo: string }' }, { code: 'type X = { foo:string }', options: ['never'] }, { code: 'type X = { foo?: string }' }, { code: 'type X = { foo?: ?string }' }, { code: 'type X = { foo?:?string }', options: ['never'] }, { code: 'type Foo = { barType: (string | () => void) }' }, { code: 'type Foo = { barType: ((string | () => void)) }' }, { code: 'type Foo = { barType:(string | () => void) }', options: ['never'] }, { code: 'type Foo = { barType:((string | () => void)) }', options: ['never'] }, { code: 'type X = { get(): A; }' }, { code: 'type X = { get(): A; }' }, { code: 'type X = { get(): A; }', options: ['never'] }, { code: 'type X = { get(): A; }', options: ['never'] }, { code: 'type X = { get: () => A; }' }, { code: 'type X = { get: () => A; }' }, { code: 'type X = { get:() => A; }', options: ['never'] }, { code: 'type X = { get:() => A; }', options: ['never'] }, { code: 'type X = { +foo: string }' }, { code: 'type X = { +foo?: string }' }, { code: 'type X = { +foo:string }', options: ['never'] }, { code: 'type X = { +foo?:string }', options: ['never'] } ] }; const OBJECT_TYPE_INDEXERS = { invalid: [ // [id:key]: value // ^ { code: 'type X = { [a:b]: c }', errors: [{message: 'There must be a space after type annotation colon.'}], options: ['always'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a: b]:c }', errors: [{message: 'There must be no space after type annotation colon.'}], options: ['never'], output: 'type X = { [a:b]:c }' }, { code: 'type X = { [a: b]: c }', errors: [{message: 'There must be 1 space after type annotation colon.'}], options: ['always'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { +[a:b]: c }', errors: [{message: 'There must be a space after type annotation colon.'}], options: ['always'], output: 'type X = { +[a: b]: c }' }, { code: 'type X = { +[a: b]:c }', errors: [{message: 'There must be no space after type annotation colon.'}], options: ['never'], output: 'type X = { +[a:b]:c }' }, { code: 'type X = { +[a: b]: c }', errors: [{message: 'There must be 1 space after type annotation colon.'}], options: ['always'], output: 'type X = { +[a: b]: c }' }, // [id:key]: value // ^ { code: 'type X = { [a: b]:c }', errors: [{message: 'There must be a space after type annotation colon.'}], options: ['always'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a:b]: c }', errors: [{message: 'There must be no space after type annotation colon.'}], options: ['never'], output: 'type X = { [a:b]:c }' }, { code: 'type X = { [a: b]: c }', errors: [{message: 'There must be 1 space after type annotation colon.'}], options: ['always'], output: 'type X = { [a: b]: c }' }, // [id:key]: value // ^ ^ { code: 'type X = { [a:b]:c }', errors: [ {message: 'There must be a space after type annotation colon.'}, {message: 'There must be a space after type annotation colon.'} ], options: ['always'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a: b]: c }', errors: [ {message: 'There must be no space after type annotation colon.'}, {message: 'There must be no space after type annotation colon.'} ], options: ['never'], output: 'type X = { [a:b]:c }' }, { code: 'type X = { [a: b]: c }', errors: [ {message: 'There must be 1 space after type annotation colon.'}, {message: 'There must be 1 space after type annotation colon.'} ], options: ['always'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a:(b)]:(c) }', errors: [ {message: 'There must be a space after type annotation colon.'}, {message: 'There must be a space after type annotation colon.'} ], options: ['always'], output: 'type X = { [a: (b)]: (c) }' }, { code: 'type X = { [a: (b)]: (c) }', errors: [ {message: 'There must be no space after type annotation colon.'}, {message: 'There must be no space after type annotation colon.'} ], options: ['never'], output: 'type X = { [a:(b)]:(c) }' } ], valid: [ { code: 'type X = { [a: b]: c }', options: ['always'] }, { code: 'type X = { [a:b]:c }', options: ['never'] }, { code: 'type X = { +[a: b]: c }', options: ['always'] }, { code: 'type X = { +[a:b]:c }', options: ['never'] } ] }; const TYPE_CAST_EXPRESSIONS = { invalid: [ { code: 'const x = ({}: {})', errors: [{message: 'There must be no space after type cast colon.'}], options: ['never'], output: 'const x = ({}:{})' }, { code: 'const x = ({}:{})', errors: [{message: 'There must be a space after type cast colon.'}], options: ['always'], output: 'const x = ({}: {})' }, { code: 'const x = ({}: {})', errors: [{message: 'There must be 1 space after type cast colon.'}], options: ['always'], output: 'const x = ({}: {})' }, { code: '((x): (string))', errors: [{message: 'There must be no space after type cast colon.'}], options: ['never'], output: '((x):(string))' }, { code: '((x):(string))', errors: [{message: 'There must be a space after type cast colon.'}], options: ['always'], output: '((x): (string))' }, { code: '((x): (string))', errors: [{message: 'There must be 1 space after type cast colon.'}], options: ['always'], output: '((x): (string))' } ], valid: [ { code: 'const x = ({}:{})', options: ['never'] }, { code: 'const x = ({}: {})', options: ['always'] }, { code: '((x):(string))', options: ['never'] }, { code: '((x): (string))', options: ['always'] } ] }; const ALL = [ ARROW_FUNCTION_PARAMS, ARROW_FUNCTION_RETURN, FUNCTION_PARAMS, FUNCTION_RETURN, FUNCTION_TYPE_PARAMS, CLASS_PROPERTIES, OBJECT_TYPE_PROPERTIES, OBJECT_TYPE_INDEXERS, TYPE_CAST_EXPRESSIONS ]; export default { invalid: _.flatMap(ALL, (rules) => { return rules.invalid; }), valid: _.flatMap(ALL, (rules) => { return rules.valid; }) }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/spaceBeforeGenericBracket.js000066400000000000000000000023431300375303300302730ustar00rootroot00000000000000export default { invalid: [ { code: 'type X = Promise ', errors: [{message: 'There must be no space before "Promise" generic type annotation bracket'}], output: 'type X = Promise' }, { code: 'type X = Promise ', errors: [{message: 'There must be no space before "Promise" generic type annotation bracket'}], options: ['never'], output: 'type X = Promise' }, { code: 'type X = Promise ', errors: [{message: 'There must be no space before "Promise" generic type annotation bracket'}], output: 'type X = Promise' }, { code: 'type X = Promise', errors: [{message: 'There must be a space before "Promise" generic type annotation bracket'}], options: ['always'], output: 'type X = Promise ' }, { code: 'type X = Promise ', errors: [{message: 'There must be one space before "Promise" generic type annotation bracket'}], options: ['always'], output: 'type X = Promise ' } ], valid: [ { code: 'type X = Promise' }, { code: 'type X = Promise ', options: ['always'] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/spaceBeforeTypeColon.js000066400000000000000000000574761300375303300273600ustar00rootroot00000000000000import _ from 'lodash'; const ARROW_FUNCTION_PARAMS = { invalid: [ { code: '(foo : string) => {}', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], options: ['never'], output: '(foo: string) => {}' }, { code: '(foo ? : string) => {}', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], options: ['never'], output: '(foo ?: string) => {}' }, { code: '(foo: string) => {}', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo : string) => {}' }, { code: '(foo : string) => {}', errors: [{message: 'There must be 1 space before "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo : string) => {}' }, { code: '(foo?: string) => {}', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo? : string) => {}' }, { code: '(foo ? : string) => {}', errors: [{message: 'There must be 1 space before "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo ? : string) => {}' }, { code: '(foo ?: string) => {}', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: '(foo ? : string) => {}' }, { code: '({ lorem, ipsum, dolor } : SomeType) => {}', errors: [{message: 'There must be no space before "{ lorem, ipsum, dolor }" parameter type annotation colon.'}], output: '({ lorem, ipsum, dolor }: SomeType) => {}' }, { code: '(foo : { a: string, b: number }) => {}', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: '(foo: { a: string, b: number }) => {}' }, { code: '({ a, b } : { a: string, b: number }) => {}', errors: [{message: 'There must be no space before "{ a, b }" parameter type annotation colon.'}], output: '({ a, b }: { a: string, b: number }) => {}' }, { code: '([ a, b ] : string[]) => {}', errors: [{message: 'There must be no space before "[ a, b ]" parameter type annotation colon.'}], output: '([ a, b ]: string[]) => {}' } ], valid: [ { code: '(foo) => {}' }, { code: '(foo: string) => {}' }, { code: '(foo?: string) => {}' }, { code: '(foo ?: string) => {}' }, { code: '(foo: string) => {}', options: ['never'] }, { code: '(foo : string) => {}', options: ['always'] }, { code: '(foo? : string) => {}', options: ['always'] }, { code: '(foo ? : string) => {}', options: ['always'] }, { code: '(foo ? : string) => {}', options: ['always'] }, { code: '({ lorem, ipsum, dolor }: SomeType) => {}' }, { code: '(foo: { a: string, b: number }) => {}' }, { code: '({ a, b }: ?{ a: string, b: number }) => {}' }, { code: '(): { a: number, b: string } => {}' }, { code: '() : { a : number, b : string } => {}', options: ['always'] }, { code: '([ a, b ]: string[]) => {}' } ] }; const ARROW_FUNCTION_RETURN = { invalid: [ { code: '() : x => {}', errors: [{message: 'There must be no space before return type colon.'}], output: '(): x => {}' }, { code: '(): x => {}', errors: [{message: 'There must be a space before return type colon.'}], options: ['always'], output: '() : x => {}' }, { code: '() : x => {}', errors: [{message: 'There must be 1 space before return type colon.'}], options: ['always'], output: '() : x => {}' } ], valid: [ { code: '(): x => {}' }, { code: '() : x => {}', options: ['always'] }, { code: '(): (number | string) => {}' }, { code: '() : (number | string) => {}', options: ['always'] } ] }; const FUNCTION_PARAMS = { invalid: [ { code: 'function x(foo : string) {}', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'function x(foo: string) {}' }, { code: 'function x(foo: string) {}', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'function x(foo : string) {}' }, { code: 'var x = function (foo : string) {}', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'var x = function (foo: string) {}' }, { code: 'var x = function (foo: string) {}', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'var x = function (foo : string) {}' }, { code: 'class Foo { constructor(foo : string ) {} }', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'class Foo { constructor(foo: string ) {} }' }, { code: 'class Foo { constructor(foo: string ) {} }', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'class Foo { constructor(foo : string ) {} }' }, { code: 'async function foo({ lorem, ipsum, dolor } : SomeType) {}', errors: [{message: 'There must be no space before "{ lorem, ipsum, dolor }" parameter type annotation colon.'}], output: 'async function foo({ lorem, ipsum, dolor }: SomeType) {}' } ], valid: [ { code: 'function x(foo: string) {}' }, { code: 'function x(foo : string) {}', options: ['always'] }, { code: 'var x = function (foo: string) {}' }, { code: 'var x = function (foo : string) {}', options: ['always'] }, { code: 'class X { foo({ bar }: Props = this.props) {} }' }, { code: 'class Foo { constructor(foo: string ) {} }' }, { code: 'class Foo { constructor(foo : string ) {} }', options: ['always'] }, { code: 'async function foo({ lorem, ipsum, dolor }: SomeType) {}' }, { code: 'function x({ a, b }: { a: string, b: number }) {}' } ] }; const FUNCTION_RETURN = { invalid: [ { code: 'function a() : x {}', errors: [{message: 'There must be no space before return type colon.'}], output: 'function a(): x {}' }, { code: 'function a(): x {}', errors: [{message: 'There must be a space before return type colon.'}], options: ['always'], output: 'function a() : x {}' }, { code: 'function a() : x {}', errors: [{message: 'There must be 1 space before return type colon.'}], options: ['always'], output: 'function a() : x {}' } ], valid: [ { code: 'function a(): x {}' }, { code: 'function a() : x {}', options: ['always'] }, { code: 'function a(): (number | string) {}' }, { code: 'function a() : (number | string) {}', options: ['always'] } ] }; const FUNCTION_TYPE_PARAMS = { invalid: [ { code: 'type X = (foo :string) => string;', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'type X = (foo:string) => string;' }, { code: 'type X = (foo:string) => string;', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'type X = (foo :string) => string;' }, { code: 'type X = (foo :string) => string;', errors: [{message: 'There must be 1 space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'type X = (foo :string) => string;' }, { code: 'type X = (foo? :string) => string;', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'type X = (foo?:string) => string;' }, { code: 'type X = (foo? :string) => string;', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'type X = (foo?:string) => string;' }, { code: 'type X = (foo?:string) => string;', errors: [{message: 'There must be a space before "foo" parameter type annotation colon.'}], options: ['always'], output: 'type X = (foo? :string) => string;' }, { code: 'type X = (foo? :?string) => string;', errors: [{message: 'There must be no space before "foo" parameter type annotation colon.'}], output: 'type X = (foo?:?string) => string;' } ], valid: [ { code: 'type X = (foo:string) => number;' }, { code: 'type X = (foo: string) => number;' }, { code: 'type X = (foo: ?string) => number;' }, { code: 'type X = (foo?: string) => number;' }, { code: 'type X = (foo?: ?string) => number;' }, { code: 'type X = (foo ?: string) => number;' }, { code: 'type X = (foo? : string) => number', options: ['always'] }, { code: 'type X = (foo? : ?string) => number', options: ['always'] } ] }; const CLASS_PROPERTIES = { invalid: [ { code: 'class X { foo :string }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], output: 'class X { foo:string }' }, { code: 'class X { foo: string }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { foo : string }' }, { code: 'class X { foo :?string }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], output: 'class X { foo:?string }' }, { code: 'class X { foo: ?string }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { foo : ?string }' }, { code: 'class X { static foo : number }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], output: 'class X { static foo: number }' }, { code: 'class X { static foo :number }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], output: 'class X { static foo:number }' }, { code: 'class X { static foo: number }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { static foo : number }' }, { code: 'class X { static foo:number }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { static foo :number }' }, { code: 'declare class Foo { static bar :number; }', errors: [{message: 'There must be no space before "bar" type annotation colon.'}], output: 'declare class Foo { static bar:number; }' }, { code: 'declare class Foo { static bar : number; }', errors: [{message: 'There must be no space before "bar" type annotation colon.'}], output: 'declare class Foo { static bar: number; }' }, { code: 'declare class Foo { static bar:number; }', errors: [{message: 'There must be a space before "bar" type annotation colon.'}], options: ['always'], output: 'declare class Foo { static bar :number; }' }, { code: 'declare class Foo { static bar: number; }', errors: [{message: 'There must be a space before "bar" type annotation colon.'}], options: ['always'], output: 'declare class Foo { static bar : number; }' }, { code: 'class X { +foo: string }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { +foo : string }' }, { code: 'class X { +foo : string }', errors: [{message: 'There must be 1 space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { +foo : string }' }, { code: 'class X { +foo : string }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { +foo: string }' }, { code: 'class X { static +foo: string }', errors: [{message: 'There must be a space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { static +foo : string }' }, { code: 'class X { static +foo : string }', errors: [{message: 'There must be 1 space before "foo" class property type annotation colon.'}], options: ['always'], output: 'class X { static +foo : string }' }, { code: 'class X { static +foo : string }', errors: [{message: 'There must be no space before "foo" class property type annotation colon.'}], options: ['never'], output: 'class X { static +foo: string }' } ], valid: [ { code: 'class Foo { bar }' }, { code: 'class Foo { bar = 3 }' }, { code: 'class Foo { bar: string }' }, { code: 'class Foo { bar: ?string }' }, { code: 'class Foo { bar:?string }' }, { code: 'class Foo { bar : string }', options: ['always'] }, { code: 'class X { static foo:number }' }, { code: 'class X { static foo: number }' }, { code: 'class X { static foo :number }', options: ['always'] }, { code: 'class X { static foo : number }', options: ['always'] }, { code: 'declare class Foo { static bar:number; }' }, { code: 'declare class Foo { static bar :number; }', options: ['always'] }, { code: 'declare class Foo { static bar: number; }' }, { code: 'declare class Foo { static bar : number; }', options: ['always'] }, { code: 'class X { +foo: string }' }, { code: 'class X { static +foo: string }' }, { code: 'class X { +foo : string }', options: ['always'] }, { code: 'class X { static +foo : string }', options: ['always'] } ] }; const OBJECT_TYPE_PROPERTIES = { invalid: [ { code: 'type X = { foo : string }', errors: [{message: 'There must be no space before "foo" type annotation colon.'}], output: 'type X = { foo: string }' }, { code: 'type X = { foo : string }', errors: [{message: 'There must be no space before "foo" type annotation colon.'}], options: ['never'], output: 'type X = { foo: string }' }, { code: 'type X = { foo: string }', errors: [{message: 'There must be a space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo : string }' }, { code: 'type X = { foo : string }', errors: [{message: 'There must be 1 space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo : string }' }, { code: 'type X = { foo? : string }', errors: [{message: 'There must be no space before "foo" type annotation colon.'}], output: 'type X = { foo?: string }' }, { code: 'type X = { foo?: string }', errors: [{message: 'There must be a space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo? : string }' }, { code: 'type X = { foo? : string }', errors: [{message: 'There must be 1 space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo? : string }' }, { code: 'type X = { foo ?: string }', errors: [{message: 'There must be a space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { foo ? : string }' }, { code: 'type X = { +foo: string }', errors: [{message: 'There must be a space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { +foo : string }' }, { code: 'type X = { +foo : string }', errors: [{message: 'There must be 1 space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { +foo : string }' }, { code: 'type X = { +foo : string }', errors: [{message: 'There must be no space before "foo" type annotation colon.'}], options: ['never'], output: 'type X = { +foo: string }' }, { code: 'type X = { +foo?: string }', errors: [{message: 'There must be a space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { +foo? : string }' }, { code: 'type X = { +foo? : string }', errors: [{message: 'There must be 1 space before "foo" type annotation colon.'}], options: ['always'], output: 'type X = { +foo? : string }' }, { code: 'type X = { +foo? : string }', errors: [{message: 'There must be no space before "foo" type annotation colon.'}], options: ['never'], output: 'type X = { +foo?: string }' } ], valid: [ { code: 'type X = { foo: string }' }, { code: 'type X = { foo : string }', options: ['always'] }, { code: 'type X = { foo?: string }' }, { code: 'type X = { foo ?: string }' }, { code: 'type X = { foo? : string }', options: ['always'] }, { code: 'type X = { +foo: string }' }, { code: 'type X = { +foo?: string }' }, { code: 'type X = { +foo : string }', options: ['always'] }, { code: 'type X = { +foo? : string }', options: ['always'] } ] }; const OBJECT_TYPE_INDEXERS = { invalid: [ // [id:key]: value // ^ { code: 'type X = { [a: b] : c }', errors: [{message: 'There must be a space before type annotation colon.'}], options: ['always'], output: 'type X = { [a : b] : c }' }, { code: 'type X = { [a : b]: c }', errors: [{message: 'There must be no space before type annotation colon.'}], options: ['never'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a : b] : c }', errors: [{message: 'There must be 1 space before type annotation colon.'}], options: ['always'], output: 'type X = { [a : b] : c }' }, { code: 'type X = { +[a:b] : c }', errors: [{message: 'There must be a space before type annotation colon.'}], options: ['always'], output: 'type X = { +[a :b] : c }' }, { code: 'type X = { +[a : b]: c }', errors: [{message: 'There must be no space before type annotation colon.'}], options: ['never'], output: 'type X = { +[a: b]: c }' }, { code: 'type X = { +[a : b] : c }', errors: [{message: 'There must be 1 space before type annotation colon.'}], options: ['always'], output: 'type X = { +[a : b] : c }' }, // [id:key]: value // ^ { code: 'type X = { [a : b]: c }', errors: [{message: 'There must be a space before type annotation colon.'}], options: ['always'], output: 'type X = { [a : b] : c }' }, { code: 'type X = { [a: b] : c }', errors: [{message: 'There must be no space before type annotation colon.'}], options: ['never'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a : b] : c }', errors: [{message: 'There must be 1 space before type annotation colon.'}], options: ['always'], output: 'type X = { [a : b] : c }' }, // [id:key]: value // ^ ^ { code: 'type X = { [a:b]:c }', errors: [ {message: 'There must be a space before type annotation colon.'}, {message: 'There must be a space before type annotation colon.'} ], options: ['always'], output: 'type X = { [a :b] :c }' }, { code: 'type X = { [a : b] : c }', errors: [ {message: 'There must be no space before type annotation colon.'}, {message: 'There must be no space before type annotation colon.'} ], options: ['never'], output: 'type X = { [a: b]: c }' }, { code: 'type X = { [a : b] : c }', errors: [ {message: 'There must be 1 space before type annotation colon.'}, {message: 'There must be 1 space before type annotation colon.'} ], options: ['always'], output: 'type X = { [a : b] : c }' }, { code: 'type X = { [a:(b)]:(c) }', errors: [ {message: 'There must be a space before type annotation colon.'}, {message: 'There must be a space before type annotation colon.'} ], options: ['always'], output: 'type X = { [a :(b)] :(c) }' }, { code: 'type X = { [a : (b)] : (c) }', errors: [ {message: 'There must be no space before type annotation colon.'}, {message: 'There must be no space before type annotation colon.'} ], options: ['never'], output: 'type X = { [a: (b)]: (c) }' } ], valid: [ { code: 'type X = { [a : b] : c }', options: ['always'] }, { code: 'type X = { [a:b]:c }', options: ['never'] }, { code: 'type X = { +[a : b] : c }', options: ['always'] }, { code: 'type X = { +[a:b]:c }', options: ['never'] }, { code: 'type X = { [a : (b)] : (c) }', options: ['always'] }, { code: 'type X = { [a:(b)]:(c) }', options: ['never'] } ] }; const TYPE_CAST_EXPRESSIONS = { invalid: [ { code: 'const x = ({} :{})', errors: [{message: 'There must be no space before type cast colon.'}], options: ['never'], output: 'const x = ({}:{})' }, { code: 'const x = ({}:{})', errors: [{message: 'There must be a space before type cast colon.'}], options: ['always'], output: 'const x = ({} :{})' }, { code: 'const x = ({} :{})', errors: [{message: 'There must be 1 space before type cast colon.'}], options: ['always'], output: 'const x = ({} :{})' }, { code: '((x) : string)', errors: [{message: 'There must be no space before type cast colon.'}], options: ['never'], output: '((x): string)' }, { code: '((x): string)', errors: [{message: 'There must be a space before type cast colon.'}], options: ['always'], output: '((x) : string)' }, { code: '((x) : string)', errors: [{message: 'There must be 1 space before type cast colon.'}], options: ['always'], output: '((x) : string)' } ], valid: [ { code: 'const x = ({}:{})', options: ['never'] }, { code: 'const x = ({} :{})', options: ['always'] }, { code: '((x): string)', options: ['never'] }, { code: '((x) : string)', options: ['always'] } ] }; const ALL = [ ARROW_FUNCTION_PARAMS, ARROW_FUNCTION_RETURN, FUNCTION_PARAMS, FUNCTION_RETURN, FUNCTION_TYPE_PARAMS, CLASS_PROPERTIES, OBJECT_TYPE_PROPERTIES, OBJECT_TYPE_INDEXERS, TYPE_CAST_EXPRESSIONS ]; export default { invalid: _.flatMap(ALL, (rules) => { return rules.invalid; }), valid: _.flatMap(ALL, (rules) => { return rules.valid; }) }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/typeIdMatch.js000066400000000000000000000011111300375303300254670ustar00rootroot00000000000000export default { invalid: [ { code: 'type foo = {};', errors: [ { message: 'Type identifier \'foo\' does not match pattern \'/^([A-Z][a-z0-9]*)+Type$/\'.' } ] }, { code: 'type FooType = {};', errors: [ { message: 'Type identifier \'FooType\' does not match pattern \'/^foo$/\'.' } ], options: [ '^foo$' ] } ], valid: [ { code: 'type FooType = {};' }, { code: 'type foo = {};', options: [ '^foo$' ] } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/unionIntersectionSpacing.js000066400000000000000000000155171300375303300303170ustar00rootroot00000000000000const UNION = { invalid: [ { code: 'type X = string| number;', errors: [{message: 'There must be a space before union type annotation separator'}], output: 'type X = string | number;' }, { code: 'type X = string| number;', errors: [{message: 'There must be a space before union type annotation separator'}], options: ['always'], output: 'type X = string | number;' }, { code: 'type X = string |number;', errors: [{message: 'There must be a space after union type annotation separator'}], output: 'type X = string | number;' }, { code: 'type X = string|number;', errors: [ {message: 'There must be a space before union type annotation separator'}, {message: 'There must be a space after union type annotation separator'} ], output: 'type X = string | number;' }, { code: 'type X = {x: string}|{y: number};', errors: [ {message: 'There must be a space before union type annotation separator'}, {message: 'There must be a space after union type annotation separator'} ], output: 'type X = {x: string} | {y: number};' }, { code: 'type X = string | number |boolean;', errors: [{message: 'There must be a space after union type annotation separator'}], output: 'type X = string | number | boolean;' }, { code: 'type X = string|number|boolean;', errors: [ {message: 'There must be a space before union type annotation separator'}, {message: 'There must be a space after union type annotation separator'}, {message: 'There must be a space before union type annotation separator'}, {message: 'There must be a space after union type annotation separator'} ], output: 'type X = string | number | boolean;' }, { code: 'type X = (string)| number;', errors: [{message: 'There must be a space before union type annotation separator'}], output: 'type X = (string) | number;' }, { code: 'type X = ((string))|(number | foo);', errors: [ {message: 'There must be a space before union type annotation separator'}, {message: 'There must be a space after union type annotation separator'} ], output: 'type X = ((string)) | (number | foo);' }, { code: 'type X = string |number;', errors: [{message: 'There must be no space before union type annotation separator'}], options: ['never'], output: 'type X = string|number;' }, { code: 'type X = string| number;', errors: [{message: 'There must be no space after union type annotation separator'}], options: ['never'], output: 'type X = string|number;' } ], valid: [ {code: 'type X = string | number;'}, {code: 'type X = string | number | boolean;'}, {code: 'type X = (string) | number;'}, {code: 'type X = ((string)) | (number | foo);'}, { code: 'type X = string|number', options: ['never'] }, { code: 'type X =\n| string\n| number' }, { code: [ 'function x() {', 'type X =', '| string', '| number', '}' ].join('\n') } ] }; const INTERSECTION = { invalid: [ { code: 'type X = string& number;', errors: [{message: 'There must be a space before intersection type annotation separator'}], output: 'type X = string & number;' }, { code: 'type X = string& number;', errors: [{message: 'There must be a space before intersection type annotation separator'}], options: ['always'], output: 'type X = string & number;' }, { code: 'type X = string &number;', errors: [{message: 'There must be a space after intersection type annotation separator'}], output: 'type X = string & number;' }, { code: 'type X = {x: string}&{y: number};', errors: [ {message: 'There must be a space before intersection type annotation separator'}, {message: 'There must be a space after intersection type annotation separator'} ], output: 'type X = {x: string} & {y: number};' }, { code: 'type X = string&number;', errors: [ {message: 'There must be a space before intersection type annotation separator'}, {message: 'There must be a space after intersection type annotation separator'} ], output: 'type X = string & number;' }, { code: 'type X = string & number &boolean;', errors: [{message: 'There must be a space after intersection type annotation separator'}], output: 'type X = string & number & boolean;' }, { code: 'type X = string&number&boolean;', errors: [ {message: 'There must be a space before intersection type annotation separator'}, {message: 'There must be a space after intersection type annotation separator'}, {message: 'There must be a space before intersection type annotation separator'}, {message: 'There must be a space after intersection type annotation separator'} ], output: 'type X = string & number & boolean;' }, { code: 'type X = (string)& number;', errors: [{message: 'There must be a space before intersection type annotation separator'}], output: 'type X = (string) & number;' }, { code: 'type X = ((string))&(number & foo);', errors: [ {message: 'There must be a space before intersection type annotation separator'}, {message: 'There must be a space after intersection type annotation separator'} ], output: 'type X = ((string)) & (number & foo);' }, { code: 'type X = string &number;', errors: [{message: 'There must be no space before intersection type annotation separator'}], options: ['never'], output: 'type X = string&number;' }, { code: 'type X = string& number;', errors: [{message: 'There must be no space after intersection type annotation separator'}], options: ['never'], output: 'type X = string&number;' } ], valid: [ {code: 'type X = string & number;'}, {code: 'type X = string & number & boolean;'}, {code: 'type X = (string) & number;'}, {code: 'type X = ((string)) & (number & foo);'}, { code: 'type X = string&number', options: ['never'] }, { code: 'type X =\n& string\n& number' }, { code: [ 'function x() {', 'type X =', '& string', '& number', '}' ].join('\n') } ] }; export default { invalid: [...UNION.invalid, ...INTERSECTION.invalid], valid: [...UNION.valid, ...INTERSECTION.valid] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/useFlowType.js000066400000000000000000000100511300375303300255450ustar00rootroot00000000000000import { RuleTester } from 'eslint'; import noUnusedVarsRule from 'eslint/lib/rules/no-unused-vars'; import useFlowType from './../../../src/rules/useFlowType'; const VALID_WITH_USE_FLOW_TYPE = [ { code: 'declare class A {}', errors: [ '\'A\' is defined but never used.' ] }, { code: 'declare function A(): Y', errors: [ '\'A\' is defined but never used.' ] }, { code: 'declare module A {}', errors: [ '\'A\' is defined but never used.' ] }, { code: 'declare module A { declare var a: Y }', errors: [ '\'A\' is defined but never used.' ] }, { code: 'declare var A: Y', errors: [ '\'A\' is defined but never used.' ] }, { code: 'import type A from "a"; (function(): T {})', errors: [ '\'A\' is defined but never used.' ] }, { code: '(function(): T {}); import type A from "a"', errors: [ '\'A\' is defined but never used.' ] }, { code: 'import type {A} from "a"; (function(): T {})', errors: [ '\'A\' is defined but never used.' ] }, { code: '(function(): T {}); import type {A} from "a"', errors: [ '\'A\' is defined but never used.' ] }, { code: '(function(): T {}); import type {a as A} from "a"', errors: [ '\'A\' is defined but never used.' ] }, { code: 'type A = {}; function x(i: Y) { i }; x()', errors: [ '\'A\' is defined but never used.' ] }, { code: 'function x(i: Y) { i }; type A = {}; x()', errors: [ '\'A\' is defined but never used.' ] }, { code: 'type A = {}; function x(i: Y) { i }; x()', // QualifiedTypeIdentifier -------^ errors: [ '\'A\' is defined but never used.' ] }, { code: 'function x(i: Y) { i }; type A = {}; x()', // ^- QualifiedTypeIdentifier errors: [ '\'A\' is defined but never used.' ] } ]; const ALWAYS_INVALID = [ { code: 'type A = Y', errors: [ '\'A\' is defined but never used.' ] }, { code: 'function x() {}; x()', errors: [ '\'A\' is defined but never used.' ] }, { code: 'import type A from "a";', errors: [ '\'A\' is defined but never used.' ] } ]; const ALWAYS_VALID = [ 'type A = Y; var x: A; x()', 'var x: A; type A = Y; x()', 'type A = Y; function x(a: A) { a() }; x()', 'function x(a: A) { a() }; type A = Y; x()', 'type A = Y; (x: A)', '(x: A); type A = Y', 'function x(): A {}; x()', 'import type A from "a"; (function(): A {})', '(function(): A {}); import type A from "a";', 'declare interface A {}', 'declare type A = {}' ]; /** * This rule is tested differently than the rest because `RuleTester` is * designed to test rule reporting and use-flow-type doesn't report * anything. use-flow-type suppresses reports from no-unused-vars. So we're * actually testing no-unused-vars's reporting with use-flow-type enabled. */ { const ruleTester = new RuleTester({ parser: 'babel-eslint' }); ruleTester.run('no-unused-vars must not trigger an error in these cases', noUnusedVarsRule, { invalid: [], valid: ALWAYS_VALID }); } { const ruleTester = new RuleTester({ parser: 'babel-eslint' }); ruleTester.run('no-unused-vars must trigger an error in these cases', noUnusedVarsRule, { invalid: [ ...ALWAYS_INVALID, ...VALID_WITH_USE_FLOW_TYPE ], valid: [] }); } { const ruleTester = new RuleTester({ parser: 'babel-eslint', rules: { 'use-flow-type': 1 } }); ruleTester.defineRule('use-flow-type', useFlowType); ruleTester.run('use-flow-type must not affect no-unused-vars behavior in these cases', noUnusedVarsRule, { invalid: ALWAYS_INVALID, valid: ALWAYS_VALID }); } export default { invalid: [], valid: [ ...VALID_WITH_USE_FLOW_TYPE.map((subject) => { return { code: subject.code, rules: { 'no-unused-vars': 1 } }; }) ] }; eslint-plugin-flowtype-2.25.0/tests/rules/assertions/validSyntax.js000066400000000000000000000003471300375303300255740ustar00rootroot00000000000000export default { invalid: [ // removed, as Babylon now prevents the invalid syntax ], valid: [ { code: 'function x(foo: string = "1") {}' }, { code: 'function x(foo: Type = bar()) {}' } ] }; eslint-plugin-flowtype-2.25.0/tests/rules/index.js000066400000000000000000000022131300375303300221750ustar00rootroot00000000000000import _ from 'lodash'; import { RuleTester } from 'eslint'; import plugin from './../../src'; const ruleTester = new RuleTester(); const reportingRules = [ 'boolean-style', 'define-flow-type', 'delimiter-dangle', 'generic-spacing', 'no-dupe-keys', 'no-weak-types', 'object-type-delimiter', 'require-parameter-type', 'require-return-type', 'require-valid-file-annotation', 'semi', 'sort-keys', 'space-after-type-colon', 'space-before-type-colon', 'space-before-generic-bracket', 'union-intersection-spacing', 'type-id-match', 'use-flow-type', 'valid-syntax' ]; const parser = require.resolve('babel-eslint'); for (const ruleName of reportingRules) { /* eslint-disable global-require */ const assertions = require('./assertions/' + _.camelCase(ruleName)); /* eslint-enable global-require */ assertions.invalid = _.map(assertions.invalid, (assertion) => { assertion.parser = parser; return assertion; }); assertions.valid = _.map(assertions.valid, (assertion) => { assertion.parser = parser; return assertion; }); ruleTester.run(ruleName, plugin.rules[ruleName], assertions); }