Skip to content

Commit f7d6bd1

Browse files
committed
Fix and cleanup prefer-read-only-props rule, closes #1326
1 parent 84ac64d commit f7d6bd1

File tree

1 file changed

+12
-14
lines changed

1 file changed

+12
-14
lines changed

packages/plugins/eslint-plugin-react-x/src/rules/prefer-read-only-props.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ export function create(context: RuleContext<MessageID, []>): RuleListener {
4646
"Program:exit"(program) {
4747
const components = ctx.getAllComponents(program);
4848
for (const [, component] of components) {
49-
if (component.id == null) continue;
50-
if (component.name == null) continue;
5149
const [props] = component.node.params;
52-
if (props == null) {
53-
continue;
54-
}
50+
// Skip if the component is anonymous to reduce false positives
51+
if (component.id == null || component.name == null) continue;
52+
// Skip if no props
53+
if (props == null) continue;
54+
5555
const propsType = getConstrainedTypeAtLocation(services, props);
5656
if (isTypeReadonly(services.program, propsType)) continue;
5757
// Handle edge case where isTypeReadonly cant detect some readonly or immutable types
@@ -76,18 +76,16 @@ function isTypeReadonlyLoose(services: ParserServicesWithTypeInformation, type:
7676
// TODO: A comprehensive test is required to verify that it works as expected
7777
// @see https://github.com/Rel1cx/eslint-react/issues/1326
7878
function isClassOrInterfaceReadonlyLoose(checker: ts.TypeChecker, type: ts.Type) {
79+
const props = type.getProperties();
7980
const baseTypes = type.getBaseTypes() ?? [];
80-
const properties = type.getProperties();
81-
if (properties.length === 0) {
81+
if (props.length === 0) {
8282
return true;
8383
}
8484
if (baseTypes.length === 0) {
85-
return properties.every((property) => isPropertyReadonlyInType(type, property.getEscapedName(), checker));
86-
}
87-
for (const property of properties) {
88-
const propertyName = property.getEscapedName();
89-
if (isPropertyReadonlyInType(type, propertyName, checker)) continue;
90-
else return baseTypes.every((heritageType) => isPropertyReadonlyInType(heritageType, propertyName, checker));
85+
return props.every((prop) => isPropertyReadonlyInType(type, prop.getEscapedName(), checker));
9186
}
92-
return true;
87+
return props.every((prop) => {
88+
if (isPropertyReadonlyInType(type, prop.getEscapedName(), checker)) return true;
89+
return baseTypes.every((type) => isPropertyReadonlyInType(type, prop.getEscapedName(), checker));
90+
});
9391
}

0 commit comments

Comments
 (0)