6
6
7
7
const utils = require ( '../utils' )
8
8
9
+ const PROPS_SEPARATOR = ', '
10
+
11
+ /**
12
+ * @param {RuleFixer } fixer
13
+ * @param {CallExpression } node
14
+ * @param {ComponentProp[] } props
15
+ * @param {RuleContext } context
16
+ */
17
+ function * fixTypeBased ( fixer , node , props , context ) {
18
+ try {
19
+ const sourceCode = context . getSourceCode ( )
20
+ const autoFixToSeparateInterface =
21
+ context . options [ 1 ] ?. autoFixToSeparateInterface || false
22
+
23
+ const propTypes = props . map ( ( prop ) =>
24
+ getComponentPropData ( prop , sourceCode )
25
+ )
26
+
27
+ const definePropsType = `{ ${ propTypes
28
+ . map (
29
+ ( { name, type, required, defaultValue } ) =>
30
+ `${ name } ${ required === false || defaultValue ? '?' : '' } : ${ type } `
31
+ )
32
+ . join ( PROPS_SEPARATOR ) } }`
33
+
34
+ // remove defineProps function parameters
35
+ yield fixer . replaceText ( node . arguments [ 0 ] , '' )
36
+
37
+ // add type annotation
38
+ if ( autoFixToSeparateInterface ) {
39
+ const variableDeclarationNode = node . parent . parent
40
+ if ( ! variableDeclarationNode ) {
41
+ return
42
+ }
43
+
44
+ yield fixer . insertTextBefore (
45
+ variableDeclarationNode ,
46
+ `interface Props ${ definePropsType . replace ( / ; / g, ',' ) } ; `
47
+ )
48
+ yield fixer . insertTextAfter ( node . callee , `<Props>` )
49
+ } else {
50
+ yield fixer . insertTextAfter ( node . callee , `<${ definePropsType } >` )
51
+ }
52
+
53
+ // add defaults if needed
54
+ const defaults = propTypes . filter ( ( { defaultValue } ) => defaultValue )
55
+ if ( defaults . length > 0 ) {
56
+ const defaultsCode = defaults
57
+ . map (
58
+ ( { name, defaultValue } ) =>
59
+ `${ name } : ${ sourceCode . getText ( defaultValue ) } `
60
+ )
61
+ . join ( PROPS_SEPARATOR )
62
+
63
+ yield fixer . insertTextBefore ( node , `withDefaults(` )
64
+ yield fixer . insertTextAfter ( node , `, { ${ defaultsCode } })` )
65
+ }
66
+ return null
67
+ } catch ( error ) {
68
+ return null
69
+ }
70
+ }
9
71
const mapNativeType = ( /** @type {string } */ nativeType ) => {
10
72
switch ( nativeType ) {
11
73
case 'String' : {
@@ -198,15 +260,12 @@ module.exports = {
198
260
} ,
199
261
/** @param {RuleContext } context */
200
262
create ( context ) {
201
- const sourceCode = context . getSourceCode ( )
202
-
203
263
const scriptSetup = utils . getScriptSetupElement ( context )
204
264
if ( ! scriptSetup || ! utils . hasAttribute ( scriptSetup , 'lang' , 'ts' ) ) {
205
265
return { }
206
266
}
207
267
208
268
const defineType = context . options [ 0 ] || 'type-based'
209
- const autoFixToSeparateInterface = context . options [ 1 ] ?. autoFixToSeparateInterface || false
210
269
211
270
return utils . defineScriptSetupVisitor ( context , {
212
271
onDefinePropsEnter ( node , props ) {
@@ -217,67 +276,7 @@ module.exports = {
217
276
node,
218
277
messageId : 'hasArg' ,
219
278
* fix ( fixer ) {
220
- try {
221
- const propTypes = props . map ( ( prop ) =>
222
- getComponentPropData ( prop , sourceCode )
223
- )
224
-
225
- const definePropsType = `{ ${ propTypes
226
- . map (
227
- ( { name, type, required, defaultValue } ) =>
228
- `${ name } ${
229
- required === false || defaultValue ? '?' : ''
230
- } : ${ type } `
231
- )
232
- . join ( ', ' ) } }`
233
-
234
- // remove defineProps function parameters
235
- yield fixer . replaceText ( node . arguments [ 0 ] , '' )
236
-
237
- // add type annotation
238
- if ( autoFixToSeparateInterface ) {
239
- const variableDeclarationNode = node . parent . parent
240
- if ( ! variableDeclarationNode ) {
241
- return
242
- }
243
-
244
- yield fixer . insertTextBefore (
245
- variableDeclarationNode ,
246
- `interface Props ${ definePropsType . replace (
247
- / ; / g,
248
- ','
249
- ) } ; `
250
- )
251
- yield fixer . insertTextAfter ( node . callee , `<Props>` )
252
- } else {
253
- yield fixer . insertTextAfter (
254
- node . callee ,
255
- `<${ definePropsType } >`
256
- )
257
- }
258
-
259
- // add defaults if needed
260
- const defaults = propTypes . filter (
261
- ( { defaultValue } ) => defaultValue
262
- )
263
- if ( defaults . length > 0 ) {
264
- const defaultsCode = defaults
265
- . map (
266
- ( { name, defaultValue } ) =>
267
- `${ name } : ${ sourceCode . getText ( defaultValue ) } `
268
- )
269
- . join ( ', ' )
270
-
271
- yield fixer . insertTextBefore ( node , `withDefaults(` )
272
- yield fixer . insertTextAfter (
273
- node ,
274
- `, { ${ defaultsCode } })`
275
- )
276
- }
277
- return null
278
- } catch ( error ) {
279
- return null
280
- }
279
+ yield * fixTypeBased ( fixer , node , props , context )
281
280
}
282
281
} )
283
282
}
0 commit comments