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

Skip to content

Commit 95d876e

Browse files
armano2JamesHenry
authored andcommitted
fix(plugin-typescript): update generic-type-naming and prefer-interface
1 parent 2e8019a commit 95d876e

File tree

3 files changed

+119
-53
lines changed

3 files changed

+119
-53
lines changed

packages/eslint-plugin-typescript/lib/rules/generic-type-naming.js

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,6 @@
55

66
const util = require('../util');
77

8-
/**
9-
*
10-
* @param {any} context ESLint context
11-
* @param {string} rule Option
12-
* @returns {Function} Node's visitor function
13-
*/
14-
function createTypeParameterChecker(context, rule) {
15-
const regex = new RegExp(rule);
16-
17-
return function checkTypeParameters(pnode) {
18-
const params = pnode.typeParameters && pnode.typeParameters.parameters;
19-
20-
if (!Array.isArray(params) || params.length === 0) {
21-
return;
22-
}
23-
params.forEach(node => {
24-
const type = node.type;
25-
26-
if (type === 'TSTypeParameter' || type === 'TypeParameter') {
27-
const name = node.name;
28-
29-
if (name && !regex.test(name)) {
30-
const data = { name, rule };
31-
32-
context.report({
33-
node,
34-
messageId: 'paramNotMatchRule',
35-
data
36-
});
37-
}
38-
}
39-
});
40-
};
41-
}
42-
438
const defaultOptions = [
449
// Matches: T , TA , TAbc , TA1Bca , T1 , T2
4510
'^T([A-Z0-9][a-zA-Z0-9]*){0,1}$'
@@ -66,16 +31,23 @@ module.exports = {
6631

6732
create(context) {
6833
const rule = util.applyDefault(defaultOptions, context.options)[0];
69-
const checkTypeParameters = createTypeParameterChecker(context, rule);
34+
const regex = new RegExp(rule);
7035

7136
return {
72-
VariableDeclarator: checkTypeParameters,
73-
ClassDeclaration: checkTypeParameters,
74-
InterfaceDeclaration: checkTypeParameters,
75-
TSInterfaceDeclaration: checkTypeParameters,
76-
FunctionDeclaration: checkTypeParameters,
77-
TSCallSignature: checkTypeParameters,
78-
CallSignature: checkTypeParameters
37+
TSTypeParameter(node) {
38+
const name =
39+
node.name && node.name.type === 'Identifier' ? node.name.name : null;
40+
41+
if (name && !regex.test(name)) {
42+
const data = { name, rule };
43+
44+
context.report({
45+
node,
46+
messageId: 'paramNotMatchRule',
47+
data
48+
});
49+
}
50+
}
7951
};
8052
}
8153
};

packages/eslint-plugin-typescript/lib/rules/prefer-interface.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,27 +35,27 @@ module.exports = {
3535
//----------------------------------------------------------------------
3636
return {
3737
// VariableDeclaration with kind type has only one VariableDeclarator
38-
"VariableDeclaration[kind='type'] > VariableDeclarator[init.type='TSTypeLiteral']"(
38+
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(
3939
node
4040
) {
4141
context.report({
42-
node,
42+
node: node.id,
4343
messageId: 'interfaceOverType',
4444
fix(fixer) {
4545
const typeNode = node.typeParameters || node.id;
4646

4747
const fixes = [
4848
fixer.replaceText(
49-
sourceCode.getFirstToken(node.parent),
49+
sourceCode.getFirstToken(node),
5050
'interface'
5151
),
5252
fixer.replaceTextRange(
53-
[typeNode.range[1], node.init.range[0]],
53+
[typeNode.range[1], node.typeAnnotation.range[0]],
5454
' '
5555
)
5656
];
5757

58-
const afterToken = sourceCode.getTokenAfter(node.init);
58+
const afterToken = sourceCode.getTokenAfter(node.typeAnnotation);
5959

6060
if (
6161
afterToken &&

packages/eslint-plugin-typescript/tests/lib/rules/generic-type-naming.js

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
/**
2+
* @fileoverview Enforces naming of generic type variables.
3+
*/
14
'use strict';
25

36
//------------------------------------------------------------------------------
@@ -23,6 +26,21 @@ ruleTester.run('generic-type-naming', rule, {
2326
{ code: 'function get<T>() {}', options: [] },
2427
{ code: 'interface GenericIdentityFn { <T>(arg: T): T }', options: [] },
2528
{ code: 'class<x> { }', options: ['^x+$'] },
29+
{ code: 'class<A> { }', options: ['^[A-Z]$'] },
30+
{
31+
code: 'class<A> extends B<Test> implements Foo<Test> { }',
32+
options: ['^[A-Z]$']
33+
},
34+
{
35+
code: `
36+
class<A> extends B<Test> implements Foo<Test> {
37+
test<Z> () {
38+
type Foo = Bar<Test>
39+
}
40+
}
41+
`,
42+
options: ['^[A-Z]$']
43+
},
2644
{
2745
code: 'class CounterContainer extends Container<Counter> { }',
2846
options: ['^T$']
@@ -49,7 +67,9 @@ ruleTester.run('generic-type-naming', rule, {
4967
errors: [
5068
{
5169
messageId: 'paramNotMatchRule',
52-
data: { name: 'x', rule: '^[A-Z]+$' }
70+
data: { name: 'x', rule: '^[A-Z]+$' },
71+
line: 1,
72+
column: 7
5373
}
5474
]
5575
},
@@ -59,7 +79,9 @@ ruleTester.run('generic-type-naming', rule, {
5979
errors: [
6080
{
6181
messageId: 'paramNotMatchRule',
62-
data: { name: 'x', rule: '^[A-Z]+$' }
82+
data: { name: 'x', rule: '^[A-Z]+$' },
83+
line: 1,
84+
column: 21
6385
}
6486
]
6587
},
@@ -69,7 +91,9 @@ ruleTester.run('generic-type-naming', rule, {
6991
errors: [
7092
{
7193
messageId: 'paramNotMatchRule',
72-
data: { name: 'x', rule: '^[A-Z]+$' }
94+
data: { name: 'x', rule: '^[A-Z]+$' },
95+
line: 1,
96+
column: 8
7397
}
7498
]
7599
},
@@ -79,7 +103,9 @@ ruleTester.run('generic-type-naming', rule, {
79103
errors: [
80104
{
81105
messageId: 'paramNotMatchRule',
82-
data: { name: 'x', rule: '^[A-Z]+$' }
106+
data: { name: 'x', rule: '^[A-Z]+$' },
107+
line: 1,
108+
column: 14
83109
}
84110
]
85111
},
@@ -89,7 +115,75 @@ ruleTester.run('generic-type-naming', rule, {
89115
errors: [
90116
{
91117
messageId: 'paramNotMatchRule',
92-
data: { name: 'x', rule: '^[A-Z]+$' }
118+
data: { name: 'x', rule: '^[A-Z]+$' },
119+
line: 1,
120+
column: 32
121+
}
122+
]
123+
},
124+
{
125+
code: `
126+
class<A> extends B<Test> implements Foo<Test> {
127+
test<Z> () {
128+
type Foo<T> = Bar<Test>
129+
}
130+
}
131+
`,
132+
options: ['^[A-Z][0-9]$'],
133+
errors: [
134+
{
135+
messageId: 'paramNotMatchRule',
136+
data: { name: 'A', rule: '^[A-Z][0-9]$' },
137+
line: 2,
138+
column: 7
139+
},
140+
{
141+
messageId: 'paramNotMatchRule',
142+
data: { name: 'Z', rule: '^[A-Z][0-9]$' },
143+
line: 3,
144+
column: 10
145+
},
146+
{
147+
messageId: 'paramNotMatchRule',
148+
data: { name: 'T', rule: '^[A-Z][0-9]$' },
149+
line: 4,
150+
column: 18
151+
}
152+
]
153+
},
154+
{
155+
code: `
156+
abstract class<A, B> extends B<Test> implements Foo<Test> {
157+
test<Z> () {
158+
type Foo<T> = Bar<Test>
159+
}
160+
}
161+
`,
162+
options: ['^[A-Z][0-9]$'],
163+
errors: [
164+
{
165+
messageId: 'paramNotMatchRule',
166+
data: { name: 'A', rule: '^[A-Z][0-9]$' },
167+
line: 2,
168+
column: 16
169+
},
170+
{
171+
messageId: 'paramNotMatchRule',
172+
data: { name: 'B', rule: '^[A-Z][0-9]$' },
173+
line: 2,
174+
column: 19
175+
},
176+
{
177+
messageId: 'paramNotMatchRule',
178+
data: { name: 'Z', rule: '^[A-Z][0-9]$' },
179+
line: 3,
180+
column: 10
181+
},
182+
{
183+
messageId: 'paramNotMatchRule',
184+
data: { name: 'T', rule: '^[A-Z][0-9]$' },
185+
line: 4,
186+
column: 18
93187
}
94188
]
95189
}

0 commit comments

Comments
 (0)