diff --git a/docs/rules/no-undefined-types.md b/docs/rules/no-undefined-types.md index 24e3604bb..9d240079a 100644 --- a/docs/rules/no-undefined-types.md +++ b/docs/rules/no-undefined-types.md @@ -865,5 +865,44 @@ quux(); /** * @type {Linters} */ + +class Filler { + static methodOne () { + return 'Method One'; + } + + nonStaticMethodTwo (param) { + return `Method Two received: ${param}`; + } + + /** + * {@link methodOne} shouldn't report eslint error + * {@link nonStaticMethodTwo} also shouldn't report eslint error + * @returns {number} A number representing the answer to everything. + */ + static methodThree () { + return 42; + } + + /** + * {@link Filler.methodOne} doesn't report eslint error + * {@link Filler.nonStaticMethodTwo} also doesn't report eslint error + * @returns {string} A string indicating the method's purpose. + */ + methodFour() { + return 'Method Four'; + } +} + +class Foo { + foo = "foo"; + /** + * Something related to {@link foo} + * @returns {string} Something awesome + */ + bar() { + return "bar"; + } +} ```` diff --git a/src/rules/noUndefinedTypes.js b/src/rules/noUndefinedTypes.js index ff45dbaec..c8c75e736 100644 --- a/src/rules/noUndefinedTypes.js +++ b/src/rules/noUndefinedTypes.js @@ -267,6 +267,31 @@ export default iterateJsdoc(({ .concat(importTags) .concat(definedTypes) .concat(/** @type {string[]} */ (definedPreferredTypes)) + .concat((() => { + // Other methods are not in scope, but we need them, and we grab them here + if (node?.type === 'MethodDefinition') { + return /** @type {import('estree').ClassBody} */ (node.parent).body.map((methodOrProp) => { + if (methodOrProp.type === 'MethodDefinition') { + // eslint-disable-next-line unicorn/no-lonely-if -- Pattern + if (methodOrProp.key.type === 'Identifier') { + return methodOrProp.key.name; + } + } + + if (methodOrProp.type === 'PropertyDefinition') { + // eslint-disable-next-line unicorn/no-lonely-if -- Pattern + if (methodOrProp.key.type === 'Identifier') { + return methodOrProp.key.name; + } + } + /* c8 ignore next 2 -- Not yet built */ + + return ''; + }).filter(Boolean); + } + + return []; + })()) .concat(...getValidRuntimeIdentifiers(node && ( (sourceCode.getScope && /* c8 ignore next 2 */ diff --git a/test/rules/assertions/noUndefinedTypes.js b/test/rules/assertions/noUndefinedTypes.js index fd2e9c4bd..a9eaec65b 100644 --- a/test/rules/assertions/noUndefinedTypes.js +++ b/test/rules/assertions/noUndefinedTypes.js @@ -1549,5 +1549,53 @@ export default /** @type {import('../index.js').TestCases} */ ({ */ `, }, + { + code: ` + class Filler { + static methodOne () { + return 'Method One'; + } + + nonStaticMethodTwo (param) { + return \`Method Two received: $\{param}\`; + } + + /** + * {@link methodOne} shouldn't report eslint error + * {@link nonStaticMethodTwo} also shouldn't report eslint error + * @returns {number} A number representing the answer to everything. + */ + static methodThree () { + return 42; + } + + /** + * {@link Filler.methodOne} doesn't report eslint error + * {@link Filler.nonStaticMethodTwo} also doesn't report eslint error + * @returns {string} A string indicating the method's purpose. + */ + methodFour() { + return 'Method Four'; + } + } + `, + }, + { + code: ` + class Foo { + foo = "foo"; + /** + * Something related to {@link foo} + * @returns {string} Something awesome + */ + bar() { + return "bar"; + } + } + `, + languageOptions: { + ecmaVersion: 2_022, + }, + }, ], });