gajus / eslint-plugin-flowtype Goto Github PK
View Code? Open in Web Editor NEWFlow type linting rules for ESLint.
License: Other
Flow type linting rules for ESLint.
License: Other
I'm currently trying to figure out what is the best solution to go forward with babel-eslint 7.x and this plugin.
We want to make the next babel-eslint version not to define or use any flow type anymore. When I pull in the dev version of babel-eslint into this plugin the whole test-suite collapses for the define & use rule. It is pretty straight forward to fix most of the cases, but I stumbled upon cases where it is now hard to test, because the two plugins are split.
Assume this example:
function x<A>() {}; x()
Previously this was always failing (A is defined but never used
) without any rule. Now babel-eslint is not doing anything to A
so this does not trigger any error by default.
What the tests should cover now is
define-flow-type
is enabled then it should faildefine-flow-type
and use-flow-type
is enabled it should still failNow the first is easy, but for the second assertion there is currently no location to test that.
This could be solved by either adding a new testfile that tests both rules together, includes the define-rule
in the use-test or by combining both rules into one.
The two rules were usually always used together afaik, but at least with the new babel-eslint version it will be nearly always necessary to use both of them when using flowtype in your code and especially when linting of flowtype is desired. So that brought up the question in my head if it makes sense to have two rules at all. Although both rules have a single responsibility right now, I think it would maybe still make sense to combine them and the underlying code could still be split into use/define.
But before I start creating a PR I wanted to get feedback and hear what you think about it @gajus
?
With the following:
async function doThing(): Promise<void> {}
a promise is implicitly returned and flow requires that you annotate it as a promise.
If you have { "annotateUndefined": true }
, this plugin does not accept throws an error since Promise<void>
is not undefined
.
flowtype/space-after-type-colon
works well in my case, but it's before counterpart does not.
I'll post a simple repro asap.
See eslint/eslint#6753 for further details.
For callbacks etc, it seems common to have function parameters that are declared (for documentation/to conform to the signature) but not used.
I'm curious what the recommended way to handle return types for render
methods of React Components is.
I'm getting warning Missing return type annotation flowtype/require-return-type
warnings for each render
method, and I'm not totally clear what return type to provide
Apologies for the noob question! But I couldn't find a clear answer elsewhere. The React example in the Flow docs don't include return types for render
Consider:
declare class Foo {
static bar:number;
}
This will output:
There must be no space after "static" type annotation colon
Hi!
I am getting this error: error 'string' is not defined no-undef
on this code:
login: (data : Object = { username: string, password: string }): Promise => {
// code
},
It is supported?
This is a screenshot from Atom:
Thanks :)
I am using the latest version of Flow, ESLint, Babel ESLint and this plugin :)
I probably missed a setting somewhere, but do optional props/params fly with arrow funcs?
(optionalProp ?: string) => { (optionalProp : string|void) }
// ^ Unexpected token (null)
Writing the above as a normal ES5 function validates fine. The pure "maybe" form seems to validate fine as an ES6 arrow func:
(maybe : ?string) => { (maybe : string|void|null) }
Hi! Would you accept a PR for a require-trailing-commas rule, enforcing this style?
type Foo = {
bar: string,
baz: string,
}
Thanks!
I might be doing something wrong. But eslint-plugin-flowtype
seem to be ignoring non-inline type declarations. Flow documentation states that there is three ways to have external type declarations:
.flowconfig
.<filename>.js.flow
.Are there some more configuraion missing from the README, or features not yet implemented?
Are there any plans to support defining flow types as comments as shown here: https://flowtype.org/blog/2015/02/20/Flow-Comments.html?
hey
Similar to #57 it would be nice to ignore the parameter for these object mappings.
const handlers = {
[REHYDRATE](state, action) {
if (action.payload.playlists) {
return { ...state, ...action.payload.playlists };
}
return { ...state };
},
...
};
[s]
Equivalent of http://eslint.org/docs/rules/space-infix-ops for spacing the flow type declaration.
@zertosh wrote https://github.com/zertosh/eslint-plugin-flow-vars in order to make sure type imports and definitions are marked as used (helpful when used in conjunction with no-unused-vars
& no-undef
). It would be great to integrate the rules from that plugin here so we can consolidate the disparate Flow-related rules into a single plugin for Flow usage. Or maybe there's a different way to achieve the same thing (not sure if we can do it via a config now or something, I'm not familiar with how that works).
Here is the error
1:19 error 'IFromPromise' is not defined no-undef
and the code can be either
declare interface IFromPromise {
value(): any,
state(): 'pending' | 'resolved' | 'rejected'
}
or
declare type IFromPromise = {
value(): any,
state(): 'pending' | 'resolved' | 'rejected'
}
changing it to declare class
fixes the issue, and an extremely weird edge case is just changing the name of the interface/type to Response
fixes the issue as well.
Hello.
I try to install the last version of the plugin but get error:
No compatible version found.Valid install targets: 0.0.0.
its only 0.0.0 on the valid versions list atm.
In version 2.11.1
interface RecordMethods<Spec: Object> {
get<A>(key: $Keys<Spec>): A;
}
Reports an error 'There must be a space after "get" type annotation colon.
This errors only goes away if get< A>
is set.
My eslint rules :
'flowtype/define-flow-type': 'error',
'flowtype/generic-spacing': ['error', 'never'],
'flowtype/require-valid-file-annotation': ['error', 'always'],
'flowtype/space-after-type-colon': ['error', 'always'],
'flowtype/space-before-type-colon': ['error', 'never'],
'flowtype/type-id-match': ['error', "^([\$]?[\A-Z][A-Za-z0-9]+)+$"],
As title states...
Given the following configuration:
"flowtype/space-after-type-colon": [
1,
"never"
]
and a function:
function fn (key: string): Object {
I get an error like this:
xxx:yy warning There must be no space after "key" parameter type annotation colon flowtype/space-after-type-colon
It applies the rule to any parameters, but it does not apply the rule to the return type. It should apply the rule to the return type as well, right?
Given this code
function aa(): (() => void) {
}
and config
flowtype/space-after-type-colon: ["warn", "always"]
Shows error "There must be 1 space after return type colon". But there is space.
Hi, I had the following error (using the eslint bug report template).
Thanks for your hard work on this plug-in !
What version of ESLint are you using?
v3.2.2
What parser (default, Babel-ESLint, etc.) are you using?
babel-eslint
Please show your full configuration:
module.exports = {
"parser": "babel-eslint",
"env": {
"es6": true,
"node": true
},
"plugins": [
"flowtype",
"json"
],
"parserOptions": {
"sourceType": "module"
},
"settings": {
"flowtype": {
"onlyFilesWithFlowAnnotation": true
}
},
"extends": "eslint:recommended",
"rules": {
"block-scoped-var": ["error"],
"consistent-return": ["error"],
"curly": ["error"],
"default-case": ["error"],
"eqeqeq": ["error"],
"no-alert": ["error"],
"no-caller": ["error"],
"no-div-regex": ["error"],
"no-eval": ["error"],
"no-extend-native": ["error"],
"no-extra-bind": ["error"],
"no-labels": ["error"],
"no-floating-decimal": ["error"],
"no-implicit-globals": ["error"],
"no-implied-eval": ["error"],
"no-invalid-this": ["error"],
"no-lone-blocks": ["error"],
"no-loop-func": ["error"],
"no-multi-spaces": ["error"],
"no-multi-str": ["error"],
"no-new": ["error"],
"no-new-func": ["error"],
"no-new-wrappers": ["error"],
"no-proto": ["error"],
"no-iterator": ["error"],
"no-return-assign": ["error"],
"no-script-url": ["error"],
"no-self-compare": ["error"],
"no-throw-literal": ["error"],
"no-unmodified-loop-condition": ["error"],
"no-unused-expressions": ["error"],
"no-useless-call": ["error"],
"no-useless-concat": ["error"],
"no-useless-escape": ["error"],
"no-void": ["error"],
"yoda": ["error", "never"],
"strict": ["error"],
"no-catch-shadow": ["error"],
"init-declarations": ["error"],
"no-label-var": ["error"],
"no-restricted-globals": ["error"],
"no-shadow": ["error"],
"no-shadow-restricted-names": ["error"],
"no-undef-init": ["error"],
"no-use-before-define": ["error"],
"no-process-env": ["error"],
"no-process-exit": ["error"],
"array-bracket-spacing": ["error"],
"brace-style": ["error", "1tbs"],
"camelcase": ["error"],
"comma-dangle": ["error"],
"comma-spacing": ["error"],
"comma-style": ["error"],
"computed-property-spacing": ["error"],
"consistent-this": ["error"],
"eol-last": ["error"],
"func-names": ["error", "never"],
"func-style": ["error", "expression"],
"indent": ["error", "tab"],
"jsx-quotes": ["error"],
"key-spacing": ["error"],
"keyword-spacing": ["error"],
"linebreak-style": ["error"],
"max-depth": ["error", {"max": 5}],
"max-len": ["error", {"code": 120}],
"max-params": ["error", {"max": 8}],
"max-statements-per-line": ["error"],
"new-cap": ["error"],
"new-parens": ["error"],
"no-array-constructor": ["error"],
"no-lonely-if": ["error"],
"no-mixed-operators": ["error"],
"no-nested-ternary": ["error"],
"no-new-object": ["error"],
"no-spaced-func": ["error"],
"no-trailing-spaces": ["error"],
"no-unneeded-ternary": ["error"],
"no-whitespace-before-property": ["error"],
"require-jsdoc": ["error", {
"require": {
"FunctionDeclaration": true,
"MethodDefinition": true,
"ClassDeclaration": false
}
}],
"valid-jsdoc": ["error", {
"requireParamDescription": false,
"requireReturnDescription": false,
"requireReturn": false
}],
"semi": ["error", "always"],
"semi-spacing": ["error"],
"space-before-blocks": ["error"],
"space-before-function-paren": ["error"],
"space-in-parens": ["error"],
"space-infix-ops": ["error"],
"space-unary-ops": ["error"],
"unicode-bom": ["error"],
"arrow-spacing": ["error"],
"no-duplicate-imports": ["error"],
"no-useless-computed-key": ["error"],
"no-useless-constructor": ["error"],
"no-useless-rename": ["error"],
"no-var": ["error"],
"prefer-rest-params": ["error"],
"rest-spread-spacing": ["error"],
"flowtype/require-parameter-type": ["error"],
"flowtype/require-return-type": ["error", "always", {"annotateUndefined": "never"}],
"flowtype/space-after-type-colon": ["error", "always"],
"flowtype/space-before-type-colon": ["error", "never"],
"flowtype/type-id-match": ["error", "^([A-Z][a-z0-9]+)+Type$"]
}
};
What did you do? Please include the actual source code causing the issue.
Linting the following file:
class Foo {
constructor (context = {} : Object) {
}
}
Via the following command:
./node_modules/.bin/eslint <Filename>
What did you expect to happen?
A message showing me detected errors or parsing errors.
What actually happened? Please include the actual, raw output from ESLint.
ESlint crashed.
Cannot read property '0' of undefined
TypeError: Cannot read property '0' of undefined
at SourceCode.api.getFirstToken (/media/p/blg/api-definition/node_modules/eslint/lib/token-store.js:153:40)
at /media/p/blg/api-definition/node_modules/eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js:26:40
at arrayEach (/media/p/blg/api-definition/node_modules/lodash/lodash.js:485:11)
at Function.forEach (/media/p/blg/api-definition/node_modules/lodash/lodash.js:8847:14)
at EventEmitter.<anonymous> (/media/p/blg/api-definition/node_modules/eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js:21:26)
at emitOne (events.js:82:20)
at EventEmitter.emit (events.js:169:7)
at NodeEventGenerator.enterNode (/media/p/blg/api-definition/node_modules/eslint/lib/util/node-event-generator.js:40:22)
at CodePathAnalyzer.enterNode (/media/p/blg/api-definition/node_modules/eslint/lib/code-path-analysis/code-path-analyzer.js:608:23)
at CommentEventGenerator.enterNode (/media/p/blg/api-definition/node_modules/eslint/lib/util/comment-event-generator.js:97:23)
With config,
"flowtype/space-after-type-colon": [2, "always"],
Code like this fails,
const Fn = ({className}:
{className?: string}) => {
There's no space directly after the colon, but a newline should count to avoid trailing whitespace.
Right now the option exists but only for arrow functions. It would be great to be able to ignore any function expression. The benefit would be for higher order functions that already have 100% Flow coverage that don't need their parameters annotated.
Example:
type Fn = (param: string) => string;
function fn1(): Fn {
return fn2(param) {
return param;
}
}
This will yield 100% Flow coverage without having to annotate fn2
.
With both activated, this will not have any errors:
type Operation = (x :number, y :number): number;
In a lot of cases the type of a variable can be asserted from the context
const myArrayOfString: String[] = ['foo', 'bar', 'bad'];
myArrayOfString.map((s) => {});
In the above example for instance, it can be asserted that s
is of type 'string'.
My request is a rule to require type annotations only where the type can not be asserted from the context.
This might not be possible/to much effort, but I thought I'd drop the idea. Hopefully, information about what variables type can be asserted is something Flow makes easily accessible.
This is incorrectly triggering the rule:
type Foo = {
barType: (string | () => void),
// ^-- warning because of parens
};
Hey,
I think I'm running into a bug with this plugin. It fails with Unsupported function signature.
everytime I use destructuring with a default parameter.
Error is:
/mocha-babel-flow/node_modules/eslint-plugin-flowtype/dist/utilities/getParameterName.js:30
throw new Error('Unsupported function signature.');
Repro repo: https://github.com/vhf/mocha-babel-flow (clone && npm run lint
)
It seems function x({ y = 1 } = {}) { }
is enough to make the crash happen.
Am I missing something?
I propose an optional configuration parameter be added for require-paremeter-type
to allow a whitelist of parameter names that will be ignored for typechecks.
{
"parser": "babel-eslint",
"plugins": [
"flowtype"
],
"rules": {
"flowtype/require-parameter-type": [
1,
"always",
{
"ignoreParameterNames": [
"_"
]
}
],
"flowtype/require-return-type": [
1,
"always",
{
"annotateUndefined": "never"
}
],
"flowtype/space-after-type-colon": [
1,
"always"
],
"flowtype/space-before-type-colon": [
1,
"never"
],
"flowtype/type-id-match": [
1,
"^([A-Z][a-z0-9]+)+Type$"
]
},
"settings": {
"flowtype": {
"onlyFilesWithFlowAnnotation": false
}
}
}
I am using reselect
in a project. Selector functions take 2 parameters, a state
and ownProps
. For some selectors, I don't need the first parameters so I call the function like so, ignoring the _
variable:
const getVideoRoot = (_, props: Object): string => props.videoRoot;
I would like to avoid typechecks on the _
parameter because I don't use it.
I would be happy to submit a PR for this if it is something you'd be willing to merge in.
I am using this plugin in conjunction with standard and run into issue with code like this:
import type {Action} from "./module"
import {init, view, update} from "./module"
I can not include Action in the same import as flow would complain that Action type is imported as value but if I don't then standard complains about duplicate errors.
const getValue = (): any => { ...}
or
render(): any {
or
constructor(props: Object) {
super(props);
or
Promise<*>
we need to prohibit these types of :) (any, blank Object, *)
With this linting configuration:
"rules": {
"flowtype/require-parameter-type": 2,
"flowtype/require-return-type": [
2,
"always",
{
"annotateUndefined": "never"
}
],
"flowtype/space-after-type-colon": [
2,
"always"
],
"flowtype/space-before-type-colon": [
2,
"never"
],
},
The following will not return a linting error:
const getUserAgent = (state: Object) => state.device.userAgent;
The following will return a false positive:
const func = (): Function => (
() => {}
);
flowtype/require-return-type Must not annotate undefined return type
The following also returns a false positive:
type ISize = {
width: number,
height: number,
};
const getScreenDimensions = (state: Object): ISize => state.device.screenDimensions;
flowtype/require-return-type Must not annotate undefined return type
eslint sees import
and import type
as equivalent, so it will throw a false no-duplicate-imports
error if you import both types and code from a module:
import type { ThingT } from './dep';
import { Thing } from './dep';
They have declined to fix this, because it is Flow-specific.
Is this something that can be fixed in this plugin?
Files that are flagged with "Flow weak" mode inevitably contain lots of non-Flow Javascript, and this plugin generates lots of false errors in such files. It would be great if we could choose to only parse Flow files that are non-weak.
Maybe I'm missing it, but are the default rules and values documented somewhere? It's not clear reading the README or https://github.com/gajus/eslint-plugin-flowtype/tree/master/.README/rules
I have a project where some parts have flow, and some do not. Is it possible to only lint the files with /* @flow */ at the top?
There are two separate symptoms here, actually.
For reference, another question on stack overflow:
http://stackoverflow.com/questions/37219362/flow-generator-type-is-not-being-recognized-by-eslint
After following the installation steps, when I run eslint on a file I get "error Definition for rule 'flowtype/require-space-after-type-colon' was not found". Is it okay to install babel-eslint and eslint-plugin-flowtype with "npm install -g"?
I also have this in my .eslintrc file:
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"globals": {
"angular": false,
"mtzEnv": false,
"$": false
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"plugins": [
"flowtype",
"react"
],
"rules": {
...
}
}
I can't find anything that describes the purpose of it. Does it invoke flow bin on my behalf? Does it make .flowconfig not necessary?
I am having issues with this plugin not showing me flow errors. I have all the rules at the strictest config:
"flowtype/define-flow-type": 2,
"flowtype/require-parameter-type": 2,
"flowtype/require-return-type": [
2,
"always",
{
"annotateUndefined": "never"
}
],
"flowtype/space-after-type-colon": [
2,
"always"
],
"flowtype/space-before-type-colon": [
2,
"never"
],
"flowtype/type-id-match": [
2,
"^([A-Z][a-z0-9]+)+Type$"
],
"flowtype/use-flow-type": 2,
"flowtype/valid-syntax": 2
and I have the following code:
This will return the error: 'Missing "player" type annotation'
setPlayer(player) {
this.setState({ currentPlayer: player });
}
While this will not show any errors
export function square(n: number): number {
return n + { foo: 'loo' };
}
Declaring a class that extends another class seems to work fine:
declare class A extends B { }
However, declaring that same class as a subclass of B, a property of C, results in an eslint error:
declare class A extends C.B { }
Flow finds no fault in the above code, and it executes fine, so I believe it should be recognized as valid syntax.
Arrow functions should be small enough that types aren't essential; it'd be nice to be able to exempt them from flowtype/require-parameter-type
and flowtype/require-return-type
However, I would not want this to affect arrow functions that are set as class properties to make bind
easier:
class Foo extends React.Component {
instancemethod = (foo: Type) : ReturnType => {
....
}
}
Is this a feasible request?
I want flowtype/require-return-type
enabled in my codebase for function
declarations and concise methods but it also complains on,
.then(profile => Profile.fromJSON(profile));
and complying is a little ugly,
.then((profile): Profile => Profile.fromJSON(profile));
I figure that Flow can generally infer the type in such small function bodies as are common with =>
and when used anonymously there's no value in hinting to the IDE.
It would be similar to type-id-match
but would enforce specific naming convention onto type parameters on polymorphic types / functions.
given the code
export default function(a: Object, b: Object): Object {
return a + b;
}
export const foo = (a: Object, b: Object): Object => {
return a + b;
};
and the config
{
"flowtype/space-after-type-colon": [2, "always"],
"flowtype/space-before-type-colon": [2, "always"],
}
I only get these errors
5:21 error There must be a space before "a" parameter type annotation colon flowtype/space-before-type-colon
5:32 error There must be a space before "b" parameter type annotation colon flowtype/space-before-type-colon
I would have expected to get these errors for the default exported function, too.
Facebook uses void
instead of undefined
in their codebase.
https://github.com/facebook/relay/blob/master/src/tools/RelayTypes.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.