@@ -73,13 +73,20 @@ function typeNeedsParentheses(node: TSESTree.Node): boolean {
73
73
}
74
74
75
75
export type OptionString = 'array' | 'generic' | 'array-simple' ;
76
- type Options = [ OptionString ] ;
76
+ type Options = [
77
+ {
78
+ default : OptionString ;
79
+ readonly ?: OptionString ;
80
+ }
81
+ ] ;
77
82
type MessageIds =
78
83
| 'errorStringGeneric'
79
84
| 'errorStringGenericSimple'
80
85
| 'errorStringArray'
81
86
| 'errorStringArraySimple' ;
82
87
88
+ const arrayOption = { enum : [ 'array' , 'generic' , 'array-simple' ] } ;
89
+
83
90
export default util . createRule < Options , MessageIds > ( {
84
91
name : 'array-type' ,
85
92
meta : {
@@ -102,14 +109,32 @@ export default util.createRule<Options, MessageIds>({
102
109
} ,
103
110
schema : [
104
111
{
105
- enum : [ 'array' , 'generic' , 'array-simple' ] ,
112
+ type : 'object' ,
113
+ properties : {
114
+ default : arrayOption ,
115
+ readonly : arrayOption ,
116
+ } ,
106
117
} ,
107
118
] ,
108
119
} ,
109
- defaultOptions : [ 'array' ] ,
110
- create ( context , [ option ] ) {
120
+ defaultOptions : [
121
+ {
122
+ default : 'array' ,
123
+ } ,
124
+ ] ,
125
+ create ( context , [ options ] ) {
111
126
const sourceCode = context . getSourceCode ( ) ;
112
127
128
+ const defaultOption = options . default ;
129
+ const readonlyOption = options . readonly || defaultOption ;
130
+
131
+ const isArraySimpleOption =
132
+ defaultOption === 'array-simple' && readonlyOption === 'array-simple' ;
133
+ const isArrayOption =
134
+ defaultOption === 'array' && readonlyOption === 'array' ;
135
+ const isGenericOption =
136
+ defaultOption === 'generic' && readonlyOption === 'generic' ;
137
+
113
138
/**
114
139
* Check if whitespace is needed before this node
115
140
* @param node the node to be evaluated.
@@ -143,22 +168,36 @@ export default util.createRule<Options, MessageIds>({
143
168
}
144
169
145
170
return {
146
- TSArrayType ( node ) {
171
+ TSArrayType ( node : TSESTree . TSArrayType ) {
147
172
if (
148
- option === 'array' ||
149
- ( option === 'array-simple' && isSimpleType ( node . elementType ) )
173
+ isArrayOption ||
174
+ ( isArraySimpleOption && isSimpleType ( node . elementType ) )
150
175
) {
151
176
return ;
152
177
}
153
- const messageId =
154
- option === 'generic'
155
- ? 'errorStringGeneric'
156
- : 'errorStringGenericSimple' ;
157
178
158
179
const isReadonly =
159
180
node . parent &&
160
181
node . parent . type === AST_NODE_TYPES . TSTypeOperator &&
161
182
node . parent . operator === 'readonly' ;
183
+
184
+ const isReadonlyGeneric =
185
+ readonlyOption === 'generic' && defaultOption !== 'generic' ;
186
+
187
+ const isReadonlyArray =
188
+ readonlyOption !== 'generic' && defaultOption === 'generic' ;
189
+
190
+ if (
191
+ ( isReadonlyGeneric && ! isReadonly ) ||
192
+ ( isReadonlyArray && isReadonly )
193
+ ) {
194
+ return ;
195
+ }
196
+
197
+ const messageId =
198
+ defaultOption === 'generic'
199
+ ? 'errorStringGeneric'
200
+ : 'errorStringGenericSimple' ;
162
201
const typeOpNode = isReadonly ? node . parent ! : null ;
163
202
164
203
context . report ( {
@@ -201,23 +240,32 @@ export default util.createRule<Options, MessageIds>({
201
240
} ,
202
241
} ) ;
203
242
} ,
243
+
204
244
TSTypeReference ( node : TSESTree . TSTypeReference ) {
205
245
if (
206
- option === 'generic' ||
246
+ isGenericOption ||
207
247
node . typeName . type !== AST_NODE_TYPES . Identifier
208
248
) {
209
249
return ;
210
250
}
211
- if ( ! [ 'Array' , 'ReadonlyArray' ] . includes ( node . typeName . name ) ) {
251
+
252
+ const isReadonlyArrayType = node . typeName . name === 'ReadonlyArray' ;
253
+ const isArrayType = node . typeName . name === 'Array' ;
254
+
255
+ if (
256
+ ! ( isArrayType || isReadonlyArrayType ) ||
257
+ ( readonlyOption === 'generic' && isReadonlyArrayType ) ||
258
+ ( defaultOption === 'generic' && ! isReadonlyArrayType )
259
+ ) {
212
260
return ;
213
261
}
214
262
215
- const messageId =
216
- option === 'array' ? 'errorStringArray' : 'errorStringArraySimple' ;
217
- const isReadonly = node . typeName . name === 'ReadonlyArray' ;
218
- const readonlyPrefix = isReadonly ? 'readonly ' : '' ;
219
-
263
+ const readonlyPrefix = isReadonlyArrayType ? 'readonly ' : '' ;
220
264
const typeParams = node . typeParameters && node . typeParameters . params ;
265
+ const messageId =
266
+ defaultOption === 'array'
267
+ ? 'errorStringArray'
268
+ : 'errorStringArraySimple' ;
221
269
222
270
if ( ! typeParams || typeParams . length === 0 ) {
223
271
// Create an 'any' array
@@ -231,12 +279,13 @@ export default util.createRule<Options, MessageIds>({
231
279
return fixer . replaceText ( node , `${ readonlyPrefix } any[]` ) ;
232
280
} ,
233
281
} ) ;
282
+
234
283
return ;
235
284
}
236
285
237
286
if (
238
287
typeParams . length !== 1 ||
239
- ( option === 'array-simple' && ! isSimpleType ( typeParams [ 0 ] ) )
288
+ ( defaultOption === 'array-simple' && ! isSimpleType ( typeParams [ 0 ] ) )
240
289
) {
241
290
return ;
242
291
}
0 commit comments