66
77const utils = require ( '../utils' )
88
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+ }
971const mapNativeType = ( /** @type {string } */ nativeType ) => {
1072 switch ( nativeType ) {
1173 case 'String' : {
@@ -198,15 +260,12 @@ module.exports = {
198260 } ,
199261 /** @param {RuleContext } context */
200262 create ( context ) {
201- const sourceCode = context . getSourceCode ( )
202-
203263 const scriptSetup = utils . getScriptSetupElement ( context )
204264 if ( ! scriptSetup || ! utils . hasAttribute ( scriptSetup , 'lang' , 'ts' ) ) {
205265 return { }
206266 }
207267
208268 const defineType = context . options [ 0 ] || 'type-based'
209- const autoFixToSeparateInterface = context . options [ 1 ] ?. autoFixToSeparateInterface || false
210269
211270 return utils . defineScriptSetupVisitor ( context , {
212271 onDefinePropsEnter ( node , props ) {
@@ -217,67 +276,7 @@ module.exports = {
217276 node,
218277 messageId : 'hasArg' ,
219278 * 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 )
281280 }
282281 } )
283282 }
0 commit comments