From 1bb4d6301b1c0c4e87a2e27e445150160315e896 Mon Sep 17 00:00:00 2001 From: Alexander T Date: Tue, 12 Nov 2019 18:20:12 +0200 Subject: [PATCH] fix(eslint-plugin): [no-type-alias] handle constructor aliases (#1198) --- .../eslint-plugin/docs/rules/no-type-alias.md | 15 +++++++++++++++ .../eslint-plugin/src/rules/no-type-alias.ts | 15 +++++++++++++++ .../tests/rules/no-type-alias.test.ts | 18 ++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/packages/eslint-plugin/docs/rules/no-type-alias.md b/packages/eslint-plugin/docs/rules/no-type-alias.md index 46230f3d329..496188d4c0a 100644 --- a/packages/eslint-plugin/docs/rules/no-type-alias.md +++ b/packages/eslint-plugin/docs/rules/no-type-alias.md @@ -84,6 +84,7 @@ or more of the following you may pass an object with the options set as follows: - `allowAliases` set to `"always"` will allow you to do aliasing (Defaults to `"never"`). - `allowCallbacks` set to `"always"` will allow you to use type aliases with callbacks (Defaults to `"never"`) +- `allowConstructors` set to `"always"` will allow you to use type aliases with constructors (Defaults to `"never"`) - `allowLiterals` set to `"always"` will allow you to use type aliases with literal objects (Defaults to `"never"`) - `allowMappedTypes` set to `"always"` will allow you to use type aliases as mapping tools (Defaults to `"never"`) - `allowTupleTypes` set to `"always"` will allow you to use type aliases with tuples (Defaults to `"never"`) @@ -248,6 +249,20 @@ type Foo = (name: string, age: number) => string | Person; type Foo = (name: string, age: number) => string & Person; ``` +### allowConstructors + +This applies to constructor types. + +The setting accepts the following values: + +- `"always"` or `"never"` to active or deactivate the feature. + +Examples of **correct** code for the `{ "allowConstructors": "always" }` option: + +```ts +type Foo = new () => void; +``` + ### allowLiterals This applies to literal types (`type Foo = { ... }`). diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index 38816b60a2f..f10fbeaf3c9 100644 --- a/packages/eslint-plugin/src/rules/no-type-alias.ts +++ b/packages/eslint-plugin/src/rules/no-type-alias.ts @@ -22,6 +22,7 @@ type Options = [ { allowAliases?: Values; allowCallbacks?: 'always' | 'never'; + allowConstructors?: 'always' | 'never'; allowLiterals?: Values; allowMappedTypes?: Values; allowTupleTypes?: Values; @@ -62,6 +63,9 @@ export default util.createRule({ allowCallbacks: { enum: ['always', 'never'], }, + allowConstructors: { + enum: ['always', 'never'], + }, allowLiterals: { enum: enumValues, }, @@ -80,6 +84,7 @@ export default util.createRule({ { allowAliases: 'never', allowCallbacks: 'never', + allowConstructors: 'never', allowLiterals: 'never', allowMappedTypes: 'never', allowTupleTypes: 'never', @@ -91,6 +96,7 @@ export default util.createRule({ { allowAliases, allowCallbacks, + allowConstructors, allowLiterals, allowMappedTypes, allowTupleTypes, @@ -220,6 +226,15 @@ export default util.createRule({ if (allowCallbacks === 'never') { reportError(type.node, type.compositionType, isTopLevel, 'Callbacks'); } + } else if (type.node.type === AST_NODE_TYPES.TSConstructorType) { + if (allowConstructors === 'never') { + reportError( + type.node, + type.compositionType, + isTopLevel, + 'Constructors', + ); + } } else if (type.node.type === AST_NODE_TYPES.TSTypeLiteral) { // literal object type checkAndReport(allowLiterals!, isTopLevel, type, 'Literals'); diff --git a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts index d17348af746..d66691dd955 100644 --- a/packages/eslint-plugin/tests/rules/no-type-alias.test.ts +++ b/packages/eslint-plugin/tests/rules/no-type-alias.test.ts @@ -439,6 +439,10 @@ type Foo = { 'type Foo = [string] & [number, number] | keyof [number, number, number];', options: [{ allowTupleTypes: 'in-unions-and-intersections' }], }, + { + code: 'type Foo = new (bar: number) => string | null;', + options: [{ allowConstructors: 'always' }], + }, ], invalid: [ { @@ -3176,5 +3180,19 @@ type Foo = { }, ], }, + { + code: 'type Foo = new (bar: number) => string | null;', + options: [{ allowConstructors: 'never' }], + errors: [ + { + messageId: 'noTypeAlias', + data: { + alias: 'constructors', + line: 1, + column: 12, + }, + }, + ], + }, ], });