Skip to content

Commit 0a8092f

Browse files
y-hsgwljharb
authored andcommitted
[types] add jsdoc type annotations
1 parent b8217ed commit 0a8092f

32 files changed

+154
-64
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1818
* [Tests] add @typescript-eslint/parser v6 ([#3629][] @HenryBrown0)
1919
* [Tests] add @typescript-eslint/parser v7 and v8 ([#3629][] @hampustagerud)
2020
* [Docs] [`no-danger`]: update broken link ([#3817][] @lucasrmendonca)
21+
* [types] add jsdoc type annotations ([#3731][] @y-hsgw)
2122

2223
[#3632]: https://github.com/jsx-eslint/eslint-plugin-react/issues/3632
2324

2425
[#3812]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3812
26+
[#3731]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3731
2527
[#3629]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3629
2628
[#3817]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3817
2729
[#3807]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3807

lib/rules/button-has-type.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ const messages = {
2828
forbiddenValue: '"{{value}}" is an invalid value for button type attribute',
2929
};
3030

31+
/** @type {import('eslint').Rule.RuleModule} */
3132
module.exports = {
3233
meta: {
3334
docs: {
@@ -149,14 +150,19 @@ module.exports = {
149150
}
150151

151152
const props = node.arguments[1].properties;
152-
const typeProp = props.find((prop) => prop.key && prop.key.name === 'type');
153+
const typeProp = props.find((prop) => (
154+
'key' in prop
155+
&& prop.key
156+
&& 'name' in prop.key
157+
&& prop.key.name === 'type'
158+
));
153159

154160
if (!typeProp) {
155161
reportMissing(node);
156162
return;
157163
}
158164

159-
checkExpression(node, typeProp.value);
165+
checkExpression(node, 'value' in typeProp ? typeProp.value : undefined);
160166
},
161167
};
162168
},

lib/rules/checked-requires-onchange-or-readonly.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const defaultOptions = {
2424
};
2525

2626
/**
27-
* @param {string[]} properties
27+
* @param {object[]} properties
2828
* @param {string} keyName
2929
* @returns {Set<string>}
3030
*/
@@ -41,6 +41,7 @@ function extractTargetProps(properties, keyName) {
4141
);
4242
}
4343

44+
/** @type {import('eslint').Rule.RuleModule} */
4445
module.exports = {
4546
meta: {
4647
docs: {

lib/rules/forbid-elements.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const messages = {
2020
forbiddenElement_message: '<{{element}}> is forbidden, {{message}}',
2121
};
2222

23+
/** @type {import('eslint').Rule.RuleModule} */
2324
module.exports = {
2425
meta: {
2526
docs: {
@@ -105,13 +106,11 @@ module.exports = {
105106
return;
106107
}
107108

108-
const argType = argument.type;
109-
110-
if (argType === 'Identifier' && /^[A-Z_]/.test(argument.name)) {
109+
if (argument.type === 'Identifier' && /^[A-Z_]/.test(argument.name)) {
111110
reportIfForbidden(argument.name, argument);
112-
} else if (argType === 'Literal' && /^[a-z][^.]*$/.test(argument.value)) {
111+
} else if (argument.type === 'Literal' && /^[a-z][^.]*$/.test(String(argument.value))) {
113112
reportIfForbidden(argument.value, argument);
114-
} else if (argType === 'MemberExpression') {
113+
} else if (argument.type === 'MemberExpression') {
115114
reportIfForbidden(getText(context, argument), argument);
116115
}
117116
},

lib/rules/forbid-foreign-prop-types.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const messages = {
1313
forbiddenPropType: 'Using propTypes from another component is not safe because they may be removed in production builds',
1414
};
1515

16+
/** @type {import('eslint').Rule.RuleModule} */
1617
module.exports = {
1718
meta: {
1819
docs: {
@@ -108,7 +109,9 @@ module.exports = {
108109
&& !ast.isAssignmentLHS(node)
109110
&& !isAllowedAssignment(node)
110111
)) || (
112+
// @ts-expect-error The JSXText type is not present in the estree type definitions
111113
(node.property.type === 'Literal' || node.property.type === 'JSXText')
114+
&& 'value' in node.property
112115
&& node.property.value === 'propTypes'
113116
&& !ast.isAssignmentLHS(node)
114117
&& !isAllowedAssignment(node)
@@ -121,7 +124,11 @@ module.exports = {
121124
},
122125

123126
ObjectPattern(node) {
124-
const propTypesNode = node.properties.find((property) => property.type === 'Property' && property.key.name === 'propTypes');
127+
const propTypesNode = node.properties.find((property) => (
128+
property.type === 'Property'
129+
&& 'name' in property.key
130+
&& property.key.name === 'propTypes'
131+
));
125132

126133
if (propTypesNode) {
127134
report(context, messages.forbiddenPropType, 'forbiddenPropType', {

lib/rules/forbid-prop-types.js

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const messages = {
2626
forbiddenPropType: 'Prop type "{{target}}" is forbidden',
2727
};
2828

29+
/** @type {import('eslint').Rule.RuleModule} */
2930
module.exports = {
3031
meta: {
3132
docs: {
@@ -192,7 +193,9 @@ module.exports = {
192193
}
193194
if (node.specifiers.length >= 1) {
194195
const propTypesSpecifier = node.specifiers.find((specifier) => (
195-
specifier.imported && specifier.imported.name === 'PropTypes'
196+
'imported' in specifier
197+
&& specifier.imported
198+
&& specifier.imported.name === 'PropTypes'
196199
));
197200
if (propTypesSpecifier) {
198201
propTypesPackageName = propTypesSpecifier.local.name;
@@ -228,12 +231,13 @@ module.exports = {
228231
return;
229232
}
230233

231-
checkNode(node.parent.right);
234+
checkNode('right' in node.parent && node.parent.right);
232235
},
233236

234237
CallExpression(node) {
235238
if (
236-
node.callee.object
239+
node.callee.type === 'MemberExpression'
240+
&& node.callee.object
237241
&& !isPropTypesPackage(node.callee.object)
238242
&& !propsUtil.isPropTypesDeclaration(node.callee)
239243
) {
@@ -242,9 +246,12 @@ module.exports = {
242246

243247
if (
244248
node.arguments.length > 0
245-
&& (node.callee.name === 'shape' || astUtil.getPropertyName(node.callee) === 'shape')
249+
&& (
250+
('name' in node.callee && node.callee.name === 'shape')
251+
|| astUtil.getPropertyName(node.callee) === 'shape'
252+
)
246253
) {
247-
checkProperties(node.arguments[0].properties);
254+
checkProperties('properties' in node.arguments[0] && node.arguments[0].properties);
248255
}
249256
},
250257

@@ -267,7 +274,7 @@ module.exports = {
267274

268275
ObjectExpression(node) {
269276
node.properties.forEach((property) => {
270-
if (!property.key) {
277+
if (!('key' in property) || !property.key) {
271278
return;
272279
}
273280

lib/rules/hook-use-state.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const messages = {
2626
suggestMemo: 'Replace useState call with useMemo',
2727
};
2828

29+
/** @type {import('eslint').Rule.RuleModule} */
2930
module.exports = {
3031
meta: {
3132
docs: {

lib/rules/jsx-closing-bracket-location.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const messages = {
2020
bracketLocation: 'The closing bracket must be {{location}}{{details}}',
2121
};
2222

23+
/** @type {import('eslint').Rule.RuleModule} */
2324
module.exports = {
2425
meta: {
2526
docs: {

lib/rules/jsx-curly-spacing.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ const messages = {
3535
spaceNeededBefore: 'A space is required before \'{{token}}\'',
3636
};
3737

38+
/** @type {import('eslint').Rule.RuleModule} */
3839
module.exports = {
3940
meta: {
4041
docs: {

lib/rules/jsx-equals-spacing.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const messages = {
2020
needSpaceAfter: 'A space is required after \'=\'',
2121
};
2222

23+
/** @type {import('eslint').Rule.RuleModule} */
2324
module.exports = {
2425
meta: {
2526
docs: {

lib/rules/jsx-fragments.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ function replaceNode(source, node, text) {
2222
}
2323

2424
const messages = {
25-
fragmentsNotSupported: 'Fragments are only supported starting from React v16.2. '
26-
+ 'Please disable the `react/jsx-fragments` rule in `eslint` settings or upgrade your version of React.',
25+
fragmentsNotSupported: 'Fragments are only supported starting from React v16.2. Please disable the `react/jsx-fragments` rule in `eslint` settings or upgrade your version of React.',
2726
preferPragma: 'Prefer {{react}}.{{fragment}} over fragment shorthand',
2827
preferFragment: 'Prefer fragment shorthand over {{react}}.{{fragment}}',
2928
};
3029

30+
/** @type {import('eslint').Rule.RuleModule} */
3131
module.exports = {
3232
meta: {
3333
docs: {
@@ -170,7 +170,7 @@ module.exports = {
170170
ImportDeclaration(node) {
171171
if (node.source && node.source.value === 'react') {
172172
node.specifiers.forEach((spec) => {
173-
if (spec.imported && spec.imported.name === fragmentPragma) {
173+
if ('imported' in spec && spec.imported && spec.imported.name === fragmentPragma) {
174174
if (spec.local) {
175175
fragmentNames.add(spec.local.name);
176176
}

lib/rules/jsx-indent-props.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ const messages = {
4545
wrongIndent: 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.',
4646
};
4747

48+
/** @type {import('eslint').Rule.RuleModule} */
4849
module.exports = {
4950
meta: {
5051
docs: {

lib/rules/jsx-indent.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const messages = {
5050
wrongIndent: 'Expected indentation of {{needed}} {{type}} {{characters}} but found {{gotten}}.',
5151
};
5252

53+
/** @type {import('eslint').Rule.RuleModule} */
5354
module.exports = {
5455
meta: {
5556
docs: {

lib/rules/jsx-no-bind.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const messages = {
2525
func: 'JSX props should not use functions',
2626
};
2727

28+
/** @type {import('eslint').Rule.RuleModule} */
2829
module.exports = {
2930
meta: {
3031
docs: {
@@ -116,7 +117,7 @@ module.exports = {
116117

117118
/**
118119
* @param {string | number} violationType
119-
* @param {any} variableName
120+
* @param {unknown} variableName
120121
* @param {string | number} blockStart
121122
*/
122123
function addVariableNameToSet(violationType, variableName, blockStart) {
@@ -175,11 +176,10 @@ module.exports = {
175176
if (
176177
blockAncestors.length > 0
177178
&& variableViolationType
179+
&& 'kind' in node.parent
178180
&& node.parent.kind === 'const' // only support const right now
179181
) {
180-
addVariableNameToSet(
181-
variableViolationType, node.id.name, blockAncestors[0].range[0]
182-
);
182+
addVariableNameToSet(variableViolationType, 'name' in node.id ? node.id.name : undefined, blockAncestors[0].range[0]);
183183
}
184184
},
185185

lib/rules/jsx-no-leaked-render.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,6 @@ function ruleFixer(context, fixStrategy, fixer, reportedNode, leftNode, rightNod
109109
throw new TypeError('Invalid value for "validStrategies" option');
110110
}
111111

112-
/**
113-
* @type {import('eslint').Rule.RuleModule}
114-
*/
115112
/** @type {import('eslint').Rule.RuleModule} */
116113
module.exports = {
117114
meta: {

lib/rules/jsx-sort-default-props.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const messages = {
2525
propsNotSorted: 'Default prop types declarations should be sorted alphabetically',
2626
};
2727

28+
/** @type {import('eslint').Rule.RuleModule} */
2829
module.exports = {
2930
meta: {
3031
deprecated: true,
@@ -178,7 +179,7 @@ module.exports = {
178179
return;
179180
}
180181

181-
checkNode(node.parent.right);
182+
checkNode('right' in node.parent && node.parent.right);
182183
},
183184

184185
Program() {

lib/rules/jsx-space-before-closing.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const messages = {
2323
needSpaceBeforeClose: 'A space is required before closing bracket',
2424
};
2525

26+
/** @type {import('eslint').Rule.RuleModule} */
2627
module.exports = {
2728
meta: {
2829
deprecated: true,
@@ -58,7 +59,7 @@ module.exports = {
5859
const sourceCode = getSourceCode(context);
5960

6061
const leftToken = getTokenBeforeClosingBracket(node);
61-
const closingSlash = sourceCode.getTokenAfter(leftToken);
62+
const closingSlash = /** @type {import("eslint").AST.Token} */ (sourceCode.getTokenAfter(leftToken));
6263

6364
if (leftToken.loc.end.line !== closingSlash.loc.start.line) {
6465
return;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy