Skip to content

Commit 8c88de2

Browse files
authored
Refactor using getPropertiesOfType
1 parent 0073358 commit 8c88de2

File tree

1 file changed

+12
-11
lines changed

1 file changed

+12
-11
lines changed

src/rules/no-unnecessary-components.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,13 @@ const components = {
1212
replacement: 'div',
1313
messageId: 'unecessaryBox',
1414
message: 'Prefer plain HTML elements over `Box` when not using `sx` for styling.',
15-
allowedProps: ['sx'], // + styled-system props
15+
allowedProps: new Set(['sx']), // + styled-system props
1616
},
1717
Text: {
1818
replacement: 'span',
1919
messageId: 'unecessarySpan',
2020
message: 'Prefer plain HTML elements over `Text` when not using `sx` for styling.',
21-
allowedProps: ['sx', 'size', 'weight'], // + styled-system props
21+
allowedProps: new Set(['sx', 'size', 'weight']), // + styled-system props
2222
},
2323
}
2424

@@ -70,6 +70,9 @@ const rule = ESLintUtils.RuleCreator.withoutDocs({
7070
const isPrimer = skipImportCheck || isPrimerComponent(name, context.sourceCode.getScope(openingElement))
7171
if (!isPrimer) return
7272

73+
/** @param {string} name */
74+
const isAllowedProp = name => componentConfig.allowedProps.has(name) || isStyledSystemProp(name)
75+
7376
// Validate the attributes and ensure an allowed prop is present or spreaded in
7477
/** @type {typeof attributes[number] | undefined | null} */
7578
let asProp = undefined
@@ -80,25 +83,23 @@ const rule = ESLintUtils.RuleCreator.withoutDocs({
8083
const typeChecker = services.program.getTypeChecker()
8184

8285
const spreadType = services.getTypeAtLocation(attribute.argument)
83-
for (const allowedProp of componentConfig.allowedProps)
84-
if (typeChecker.getPropertyOfType(spreadType, allowedProp) !== undefined) return
8586

8687
// Check if the spread type has a string index signature - this could hide an allowed property
8788
if (typeChecker.getIndexTypeOfType(spreadType, IndexKind.String) !== undefined) return
8889

90+
const spreadPropNames = typeChecker.getPropertiesOfType(spreadType).map(prop => prop.getName())
91+
92+
// If an allowed prop gets spread in, this is a valid use of the component
93+
if (spreadPropNames.some(isAllowedProp)) return
94+
8995
// If there is an `as` inside the spread object, we can't autofix reliably
90-
if (typeChecker.getPropertyOfType(spreadType, 'as') !== undefined) asProp = null
96+
if (spreadPropNames.includes('as')) asProp = null
9197

9298
continue
9399
}
94100

95101
// Has an allowed prop, so should keep using this component
96-
for (const allowedProp of componentConfig.allowedProps)
97-
if (
98-
attribute.name.type === 'JSXIdentifier' &&
99-
(attribute.name.name === allowedProp || isStyledSystemProp(attribute.name.name))
100-
)
101-
return
102+
if (attribute.name.type === 'JSXIdentifier' && isAllowedProp(attribute.name.name)) return
102103

103104
// If there is an `as` prop we will need to account for that when autofixing
104105
if (attribute.name.type === 'JSXIdentifier' && attribute.name.name === 'as') asProp = attribute

0 commit comments

Comments
 (0)