gajus / eslint-plugin-jsdoc

JSDoc specific linting rules for ESLint.
Other
1.08k stars 155 forks source link

JSDoc should be positioned above all overloads when using TypeScript function overloading #1189

Closed PindaPixel closed 6 months ago

PindaPixel commented 6 months ago

Expected behavior

With the following snippet the TypeScript language service correctly displays the JSDoc when inspecting the function, and I expect jsdoc/require-jsdoc to know the function is documented.

/**
 * @param a Some description
 * @param b Some other description
 * @returns The sum of a and b
 */
function add(a:string, b:string):string;
function add(a:number, b:number): number;
function add(a: any, b:any): any {
    return a + b;
}

Actual behavior

The require-doc rule reports that the function is missing a JSDoc comment and expects the JSDoc to be positioned under the overloads, but this way the TypeScript language service does not display the given docs upon inspection.

function add(a:string, b:string):string;
function add(a:number, b:number): number;
/**
 * @param a Some description
 * @param b Some other description
 * @returns The sum of a and b
 */
function add(a: any, b:any): any {
    return a + b;
}

See TypeScript language service behaviour in this example.

ESLint Config

//eslint.config.js
import jsdoc from "eslint-plugin-jsdoc";

export default [jsdoc.configs["flat/recommended-typescript"]];

Environment

brettz9 commented 6 months ago

There should ideally be some better defaulting behavior here, but currently you can workaround this, by adding a custom rule definition for jsdoc/require-jsdoc:

'jsdoc/require-jsdoc': ['warn', {
  contexts: [
    // Expect JSDoc for TypeScript overloads which are not preceded by another overload
    'TSDeclareFunction:not(TSDeclareFunction + TSDeclareFunction)',
    // Expect JSDoc for regular function declarations which are not preceded by an overload
    'FunctionDeclaration:not(TSDeclareFunction + FunctionDeclaration)',
  ],
  require: {
    // Disable the default Function declaration behavior (which applies regardless of preceding overload)
    FunctionDeclaration: false,
  },
}]

Ideally, we'd set up any other reasonable contexts for TypeScript, but besides for other cases like this, we don't want to add default requirements beyond looking for JSDoc blocks above function types since projects may differ about the constructs for which they desire JSDoc.

PindaPixel commented 6 months ago

Thanks a lot, this is good enough for me. Only downside is that if overload signatures don't match jsdoc/check-param-names will report an error @param "parametername" does not match an existing function parameter.

Crude example:

function myFunc(id: string): number;
function myFunc(id: `${number}`, format: NumberFormat): number

Will report that format doesn't exist.

saltman424 commented 3 months ago

For future reference, since I just encountered issues around how to apply this for exported functions and methods: I believe this issue is actually a duplicate of #666. In that issue, there is a comment listing additional contexts that can be used to match exported functions and methods