diff --git a/packages/eslint-plugin/docs/rules/no-type-alias.md b/packages/eslint-plugin/docs/rules/no-type-alias.md index 496188d4c0a..1927fdd54c9 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"`) +- `allowConditionalTypes` set to `"always"` will allow you to use type aliases with conditional types (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"`) @@ -249,6 +250,16 @@ type Foo = (name: string, age: number) => string | Person; type Foo = (name: string, age: number) => string & Person; ``` +### allowConditionalTypes + +This applies to conditional types. + +Examples of **correct** code for the `{ "allowConditionalTypes": "always" }` option: + +```ts +type Foo = T extends number ? number : null; +``` + ### allowConstructors This applies to constructor types. diff --git a/packages/eslint-plugin/src/rules/no-type-alias.ts b/packages/eslint-plugin/src/rules/no-type-alias.ts index f10fbeaf3c9..02aca84e315 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'; + allowConditionalTypes?: 'always' | 'never'; allowConstructors?: 'always' | 'never'; allowLiterals?: Values; allowMappedTypes?: Values; @@ -63,6 +64,9 @@ export default util.createRule({ allowCallbacks: { enum: ['always', 'never'], }, + allowConditionalTypes: { + enum: ['always', 'never'], + }, allowConstructors: { enum: ['always', 'never'], }, @@ -84,6 +88,7 @@ export default util.createRule({ { allowAliases: 'never', allowCallbacks: 'never', + allowConditionalTypes: 'never', allowConstructors: 'never', allowLiterals: 'never', allowMappedTypes: 'never', @@ -96,6 +101,7 @@ export default util.createRule({ { allowAliases, allowCallbacks, + allowConditionalTypes, allowConstructors, allowLiterals, allowMappedTypes, @@ -226,6 +232,16 @@ export default util.createRule({ if (allowCallbacks === 'never') { reportError(type.node, type.compositionType, isTopLevel, 'Callbacks'); } + } else if (type.node.type === AST_NODE_TYPES.TSConditionalType) { + // conditional type + if (allowConditionalTypes === 'never') { + reportError( + type.node, + type.compositionType, + isTopLevel, + 'Conditional types', + ); + } } else if (type.node.type === AST_NODE_TYPES.TSConstructorType) { if (allowConstructors === 'never') { reportError( 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 d66691dd955..be5ca84b9e5 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 MyType = T extends number ? number : null;', + options: [{ allowConditionalTypes: 'always' }], + }, { code: 'type Foo = new (bar: number) => string | null;', options: [{ allowConstructors: 'always' }], @@ -3188,9 +3192,36 @@ type Foo = { messageId: 'noTypeAlias', data: { alias: 'constructors', - line: 1, - column: 12, }, + line: 1, + column: 12, + }, + ], + }, + { + code: 'type MyType = T extends number ? number : null;', + errors: [ + { + messageId: 'noTypeAlias', + data: { + alias: 'conditional types', + }, + line: 1, + column: 18, + }, + ], + }, + { + code: 'type MyType = T extends number ? number : null;', + options: [{ allowConditionalTypes: 'never' }], + errors: [ + { + messageId: 'noTypeAlias', + data: { + alias: 'conditional types', + }, + line: 1, + column: 18, }, ], },