Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4195919

Browse files
authored
feat(eslint-plugin): [no-type-alias]: add allowGenerics option (typescript-eslint#3865)
1 parent 25a42c0 commit 4195919

File tree

3 files changed

+57
-0
lines changed

3 files changed

+57
-0
lines changed

packages/eslint-plugin/docs/rules/no-type-alias.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ or more of the following you may pass an object with the options set as follows:
8989
- `allowLiterals` set to `"always"` will allow you to use type aliases with literal objects (Defaults to `"never"`)
9090
- `allowMappedTypes` set to `"always"` will allow you to use type aliases as mapping tools (Defaults to `"never"`)
9191
- `allowTupleTypes` set to `"always"` will allow you to use type aliases with tuples (Defaults to `"never"`)
92+
- `allowGenerics` set to `"always"` will allow you to use type aliases with generics (Defaults to `"never"`)
9293

9394
### `allowAliases`
9495

@@ -555,6 +556,28 @@ type Foo = [number] & [number, number];
555556
type Foo = [string] | [number];
556557
```
557558

559+
### `allowGenerics`
560+
561+
This applies to generic types, including TypeScript provided global utility types (`type Foo = Record<string, number>`).
562+
563+
The setting accepts the following options:
564+
565+
- `"always"` or `"never"` to active or deactivate the feature.
566+
567+
Examples of **correct** code for the `{ "allowGenerics": "always" }` options:
568+
569+
```ts
570+
type Foo = Bar<string>;
571+
572+
type Foo = Record<string, number>;
573+
574+
type Foo = Readonly<Bar>;
575+
576+
type Foo = Partial<Bar>;
577+
578+
type Foo = Omit<Bar, 'a' | 'b'>;
579+
```
580+
558581
## When Not To Use It
559582

560583
When you can't express some shape with an interface or you need to use a union, tuple type,

packages/eslint-plugin/src/rules/no-type-alias.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Options = [
2727
allowLiterals?: Values;
2828
allowMappedTypes?: Values;
2929
allowTupleTypes?: Values;
30+
allowGenerics?: 'always' | 'never';
3031
},
3132
];
3233
type MessageIds = 'noTypeAlias' | 'noCompositionAlias';
@@ -79,6 +80,9 @@ export default util.createRule<Options, MessageIds>({
7980
allowTupleTypes: {
8081
enum: enumValues,
8182
},
83+
allowGenerics: {
84+
enum: ['always', 'never'],
85+
},
8286
},
8387
additionalProperties: false,
8488
},
@@ -93,6 +97,7 @@ export default util.createRule<Options, MessageIds>({
9397
allowLiterals: 'never',
9498
allowMappedTypes: 'never',
9599
allowTupleTypes: 'never',
100+
allowGenerics: 'never',
96101
},
97102
],
98103
create(
@@ -106,6 +111,7 @@ export default util.createRule<Options, MessageIds>({
106111
allowLiterals,
107112
allowMappedTypes,
108113
allowTupleTypes,
114+
allowGenerics,
109115
},
110116
],
111117
) {
@@ -203,6 +209,13 @@ export default util.createRule<Options, MessageIds>({
203209
return false;
204210
};
205211

212+
const isValidGeneric = (type: TypeWithLabel): boolean => {
213+
return (
214+
type.node.type === AST_NODE_TYPES.TSTypeReference &&
215+
type.node.typeParameters !== undefined
216+
);
217+
};
218+
206219
const checkAndReport = (
207220
optionValue: Values,
208221
isTopLevel: boolean,
@@ -260,6 +273,10 @@ export default util.createRule<Options, MessageIds>({
260273
} else if (isValidTupleType(type)) {
261274
// tuple types
262275
checkAndReport(allowTupleTypes!, isTopLevel, type, 'Tuple Types');
276+
} else if (isValidGeneric(type)) {
277+
if (allowGenerics === 'never') {
278+
reportError(type.node, type.compositionType, isTopLevel, 'Generics');
279+
}
263280
} else if (
264281
// eslint-disable-next-line @typescript-eslint/internal/prefer-ast-types-enum
265282
type.node.type.endsWith('Keyword') ||

packages/eslint-plugin/tests/rules/no-type-alias.test.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,10 @@ type KeyNames = keyof typeof SCALARS;
481481
code: 'type Foo = new (bar: number) => string | null;',
482482
options: [{ allowConstructors: 'always' }],
483483
},
484+
{
485+
code: 'type Foo = Record<string, number>;',
486+
options: [{ allowGenerics: 'always' }],
487+
},
484488
],
485489
invalid: [
486490
{
@@ -3329,5 +3333,18 @@ type Foo<T> = {
33293333
},
33303334
],
33313335
},
3336+
{
3337+
code: 'type Foo = Record<string, number>;',
3338+
errors: [
3339+
{
3340+
messageId: 'noTypeAlias',
3341+
data: {
3342+
alias: 'generics',
3343+
},
3344+
line: 1,
3345+
column: 12,
3346+
},
3347+
],
3348+
},
33323349
],
33333350
});

0 commit comments

Comments
 (0)