pax_global_header 0000666 0000000 0000000 00000000064 13003753033 0014507 g ustar 00root root 0000000 0000000 52 comment=8f355c2b6e37ee391e35c8283ba879591f69a8c9
eslint-plugin-flowtype-2.25.0/ 0000775 0000000 0000000 00000000000 13003753033 0016236 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/.README/ 0000775 0000000 0000000 00000000000 13003753033 0017251 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/.README/README.md 0000664 0000000 0000000 00000010554 13003753033 0020535 0 ustar 00root root 0000000 0000000 # eslint-plugin-flowtype
[](https://www.npmjs.org/package/eslint-plugin-flowtype)
[](https://travis-ci.org/gajus/eslint-plugin-flowtype)
[](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/ 0000775 0000000 0000000 00000000000 13003753033 0020403 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/.README/rules/boolean-style.md 0000664 0000000 0000000 00000000673 13003753033 0023510 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000311 13003753033 0024076 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000001544 13003753033 0024137 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000770 13003753033 0023767 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000416 13003753033 0023246 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000001505 13003753033 0023431 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000001046 13003753033 0025127 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000002237 13003753033 0025342 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000001410 13003753033 0024671 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000002005 13003753033 0026560 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000665 13003753033 0021671 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000001362 13003753033 0022667 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000752 13003753033 0025212 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000761 13003753033 0026307 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000756 13003753033 0025357 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000604 13003753033 0023372 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000772 13003753033 0026211 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000416 13003753033 0023446 0 ustar 00root root 0000000 0000000 ### `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.md 0000664 0000000 0000000 00000000255 13003753033 0023352 0 ustar 00root root 0000000 0000000 ### `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/.babelrc 0000664 0000000 0000000 00000000164 13003753033 0017632 0 ustar 00root root 0000000 0000000 {
"presets": [
"es2015",
"stage-0"
],
"plugins": [
"add-module-exports"
]
}
eslint-plugin-flowtype-2.25.0/.eslintrc 0000664 0000000 0000000 00000000037 13003753033 0020062 0 ustar 00root root 0000000 0000000 {
"extends": "canonical"
}
eslint-plugin-flowtype-2.25.0/.gitignore 0000775 0000000 0000000 00000000161 13003753033 0020227 0 ustar 00root root 0000000 0000000 node_modules
coverage
dist
*.log
.*
!.eslintrc
!.gitignore
!.npmignore
!.babelrc
!.travis.yml
!.README
!.scripts
eslint-plugin-flowtype-2.25.0/.npmignore 0000775 0000000 0000000 00000000034 13003753033 0020235 0 ustar 00root root 0000000 0000000 src
tests
coverage
.*
*.log
eslint-plugin-flowtype-2.25.0/.scripts/ 0000775 0000000 0000000 00000000000 13003753033 0020003 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/.scripts/release.sh 0000775 0000000 0000000 00000002771 13003753033 0021771 0 ustar 00root root 0000000 0000000 #!/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.yml 0000664 0000000 0000000 00000000566 13003753033 0020356 0 ustar 00root root 0000000 0000000 language: 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.md 0000664 0000000 0000000 00000017611 13003753033 0020055 0 ustar 00root root 0000000 0000000 # 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.md 0000664 0000000 0000000 00000003067 13003753033 0020475 0 ustar 00root root 0000000 0000000 # 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/LICENSE 0000664 0000000 0000000 00000002771 13003753033 0017252 0 ustar 00root root 0000000 0000000 Copyright (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.md 0000664 0000000 0000000 00000242511 13003753033 0017522 0 ustar 00root root 0000000 0000000
# eslint-plugin-flowtype
[](https://www.npmjs.org/package/eslint-plugin-flowtype)
[](https://travis-ci.org/gajus/eslint-plugin-flowtype)
[](https://github.com/gajus/canonical)
[Flow type](http://flowtype.org/) linting rules for ESLint.
* [eslint-plugin-flowtype](#eslint-plugin-flowtype)
* [Installation](#eslint-plugin-flowtype-installation)
* [Configuration](#eslint-plugin-flowtype-configuration)
* [Shareable configurations](#eslint-plugin-flowtype-configuration-shareable-configurations)
* [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/ 0000775 0000000 0000000 00000000000 13003753033 0017006 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/bin/readmeAssertions.js 0000664 0000000 0000000 00000004551 13003753033 0022661 0 ustar 00root root 0000000 0000000 /**
* 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.json 0000664 0000000 0000000 00000003441 13003753033 0020526 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 13003753033 0017025 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/src/configs/ 0000775 0000000 0000000 00000000000 13003753033 0020455 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/src/configs/recommended.json 0000664 0000000 0000000 00000001626 13003753033 0023637 0 ustar 00root root 0000000 0000000 {
"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.js 0000664 0000000 0000000 00000004675 13003753033 0020506 0 ustar 00root root 0000000 0000000 import 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/ 0000775 0000000 0000000 00000000000 13003753033 0020157 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/src/rules/booleanStyle.js 0000664 0000000 0000000 00000001241 13003753033 0023153 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000003541 13003753033 0023444 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000004353 13003753033 0023613 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000005167 13003753033 0023447 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000001172 13003753033 0022604 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000002023 13003753033 0022763 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000002422 13003753033 0024464 0 ustar 00root root 0000000 0000000 // 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.js 0000664 0000000 0000000 00000002611 13003753033 0024674 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000006473 13003753033 0024245 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000003404 13003753033 0026005 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000002171 13003753033 0021453 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000004412 13003753033 0022341 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000000271 13003753033 0024427 0 ustar 00root root 0000000 0000000 import 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.js 0000664 0000000 0000000 00000002566 13003753033 0025535 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000000254 13003753033 0024571 0 ustar 00root root 0000000 0000000 import makeSpacing from './typeColonSpacing';
export default (context) => {
return makeSpacing('before', context, {
always: context.options[0] === 'always'
});
};
eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/ 0000775 0000000 0000000 00000000000 13003753033 0023440 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/src/rules/typeColonSpacing/evaluateFunctions.js 0000664 0000000 0000000 00000000757 13003753033 0027506 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000001103 13003753033 0031107 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000002266 13003753033 0031350 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000000771 13003753033 0027653 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000000427 13003753033 0031344 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000001413 13003753033 0027131 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000001431 13003753033 0025104 0 ustar 00root root 0000000 0000000 import 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.js 0000664 0000000 0000000 00000002427 13003753033 0025645 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000001024 13003753033 0022725 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000003642 13003753033 0025546 0 ustar 00root root 0000000 0000000 import {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.js 0000664 0000000 0000000 00000001624 13003753033 0023006 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000001625 13003753033 0023027 0 ustar 00root root 0000000 0000000 import _ 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/ 0000775 0000000 0000000 00000000000 13003753033 0021040 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/src/utilities/getParameterName.js 0000664 0000000 0000000 00000002526 13003753033 0024624 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000000426 13003753033 0025313 0 ustar 00root root 0000000 0000000 const 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.js 0000664 0000000 0000000 00000000432 13003753033 0025451 0 ustar 00root root 0000000 0000000 const 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.js 0000664 0000000 0000000 00000000670 13003753033 0022510 0 ustar 00root root 0000000 0000000 '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.js 0000664 0000000 0000000 00000000427 13003753033 0023444 0 ustar 00root root 0000000 0000000 import 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.js 0000664 0000000 0000000 00000000753 13003753033 0025501 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000000473 13003753033 0025536 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000000106 13003753033 0023331 0 ustar 00root root 0000000 0000000 export default (name) => {
return name ? '"' + name + '" ' : '';
};
eslint-plugin-flowtype-2.25.0/src/utilities/spacingFixers.js 0000664 0000000 0000000 00000001567 13003753033 0024214 0 ustar 00root root 0000000 0000000 export 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/ 0000775 0000000 0000000 00000000000 13003753033 0017400 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/tests/rules/ 0000775 0000000 0000000 00000000000 13003753033 0020532 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/tests/rules/assertions/ 0000775 0000000 0000000 00000000000 13003753033 0022724 5 ustar 00root root 0000000 0000000 eslint-plugin-flowtype-2.25.0/tests/rules/assertions/booleanStyle.js 0000664 0000000 0000000 00000001247 13003753033 0025726 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000010170 13003753033 0026205 0 ustar 00root root 0000000 0000000 import {
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.js 0000664 0000000 0000000 00000033506 13003753033 0026362 0 ustar 00root root 0000000 0000000 const 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.js 0000664 0000000 0000000 00000007375 13003753033 0026217 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000000601 13003753033 0025345 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000012575 13003753033 0025545 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000010622 13003753033 0027232 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000006703 13003753033 0027447 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000020735 13003753033 0027007 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000004453 13003753033 0030557 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000001757 13003753033 0024231 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000005657 13003753033 0025122 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000071646 13003753033 0027212 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000002343 13003753033 0030273 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000057476 13003753033 0027360 0 ustar 00root root 0000000 0000000 import _ 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.js 0000664 0000000 0000000 00000001111 13003753033 0025467 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000015517 13003753033 0030317 0 ustar 00root root 0000000 0000000 const 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.js 0000664 0000000 0000000 00000010051 13003753033 0025545 0 ustar 00root root 0000000 0000000 import {
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.js 0000664 0000000 0000000 00000000347 13003753033 0025574 0 ustar 00root root 0000000 0000000 export 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.js 0000664 0000000 0000000 00000002213 13003753033 0022175 0 ustar 00root root 0000000 0000000 import _ 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);
}