diff --git a/.README/rules/require-compound-type-alias.md b/.README/rules/require-compound-type-alias.md index 59cac7f4..1ac67c9c 100644 --- a/.README/rules/require-compound-type-alias.md +++ b/.README/rules/require-compound-type-alias.md @@ -1,14 +1,32 @@ ### `require-compound-type-alias` -Requires to make a type alias for all [union](https://flow.org/en/docs/types/unions/) and [intersection](https://flow.org/en/docs/types/intersections/) types. If these are used in "raw" forms it might be tempting to just copy&paste them around the code. However, this brings sort of a source code pollution and unnecessary changes on several parts when these compound types need to be changed. +Requires to make a type alias for all [union](https://flow.org/en/docs/types/unions/) and [intersection](https://flow.org/en/docs/types/intersections/) types. If these are used in "raw" forms it might be tempting to just copy & paste them around the code. However, this brings sort of a source code pollution and unnecessary changes on several parts when these compound types need to be changed. #### Options -The rule has a string option: +The rule has two options: +1. a string option + +* `"always"` (default) * `"never"` -* `"always"` -The default value is `"always"`. +2. an object + +```js +{ + "rules": { + "flowtype/require-compound-type-alias": [ + 2, + "always", + { + "allowNull": true + } + ] + } +} +``` + +* `allowNull` – allows compound types where one of the members is a `null`, e.g. `string | null`. diff --git a/.README/rules/type-id-match.md b/.README/rules/type-id-match.md index 6fe93027..f5f6036c 100644 --- a/.README/rules/type-id-match.md +++ b/.README/rules/type-id-match.md @@ -4,7 +4,7 @@ Enforces a consistent naming pattern for type aliases. #### Options -This rule needs a text RegExp to operate with Its signature is as follows: +This rule requires a text RegExp: ```js { diff --git a/package.json b/package.json index 06bcef5a..983c94ea 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "chai": "^4.2.0", "eclint": "^2.8.1", "eslint": "^7.0.0", - "eslint-config-canonical": "^19.0.5", + "eslint-config-canonical": "^20.0.4", "gitdown": "^3.1.3", "glob": "^7.1.6", "husky": "^4.2.5", diff --git a/src/rules/requireCompoundTypeAlias.js b/src/rules/requireCompoundTypeAlias.js index f056c39b..996ef2fb 100644 --- a/src/rules/requireCompoundTypeAlias.js +++ b/src/rules/requireCompoundTypeAlias.js @@ -3,14 +3,36 @@ const schema = [ enum: ['always', 'never'], type: 'string', }, + { + additionalProperties: false, + properties: { + allowNull: { + type: 'boolean', + }, + }, + type: 'object', + }, ]; const create = (context) => { const always = (context.options[0] || 'always') === 'always'; + const allowNull = !(context.options[1] && context.options[1].allowNull === false); + if (always) { return { IntersectionTypeAnnotation (node) { + if ( + allowNull && + node.types.length === 2 && + ( + node.types[0].type === 'NullLiteralTypeAnnotation' || + node.types[1].type === 'NullLiteralTypeAnnotation' + ) + ) { + return; + } + if (node.parent.type !== 'TypeAlias') { context.report({ message: 'All intersection types must be declared with named type alias.', @@ -19,6 +41,17 @@ const create = (context) => { } }, UnionTypeAnnotation (node) { + if ( + allowNull && + node.types.length === 2 && + ( + node.types[0].type === 'NullLiteralTypeAnnotation' || + node.types[1].type === 'NullLiteralTypeAnnotation' + ) + ) { + return; + } + if (node.parent.type !== 'TypeAlias') { context.report({ message: 'All union types must be declared with named type alias.', diff --git a/tests/rules/assertions/requireCompoundTypeAlias.js b/tests/rules/assertions/requireCompoundTypeAlias.js index 3e116f3f..0a72856f 100644 --- a/tests/rules/assertions/requireCompoundTypeAlias.js +++ b/tests/rules/assertions/requireCompoundTypeAlias.js @@ -1,5 +1,15 @@ export default { invalid: [ + { + code: 'const foo: string | null = null;', + errors: [{message: 'All union types must be declared with named type alias.'}], + options: [ + 'always', + { + allowNull: false, + }, + ], + }, { code: 'function foo(bar: "A" | "B") {}', errors: [{message: 'All union types must be declared with named type alias.'}], @@ -65,6 +75,18 @@ export default { }, ], valid: [ + { + code: 'const foo: string | null = null;', + }, + { + code: 'const foo: string | null = null;', + options: [ + 'always', + { + allowNull: true, + }, + ], + }, { code: 'type Foo = "A" | "B";', },