Skip to content

Native LS: JSDoc @this / @param types are any for hover & completions (checker OK) #65167

Open

Description

🔎 Search Terms

JSDoc Sajith Ariyarathna (@this), completions, this., checkJs, getCompletionsAtPosition, contextual this

🕗 Version & Regression Information

  • Classic typescript@6.0.3 language service: completions on this. inside a JSDoc-@this-annotated function list the annotated members
  • Native LS on current main (7.1.0-dev): no completion list (nil / empty) at the same position
  • Checker still applies @this correctly (e.g. this.missing → TS2339); only completions are broken
  • Control: the equivalent TypeScript this parameter form works on native

💻 Code

// @allowJs: true
// @checkJs: true
/**
 * @this {{ id: string, click: () => void }}
 * @param {string} ev
 */
function h(ev) {
  this./*completions here*/
}

Also fails with DOM types:

// @lib: dom,es2020
/**
 * @this {HTMLElement}
 */
function h() {
  this./*completions here*/
}

Working native control (TS this param):

function h(this: { id: string, click: () => void }, ev: string) {
  this./*id, click offered*/
}

Checker still sees the @this type:

/**
 * @this {{ id: string, click: () => void }}
 */
function h() {
  this.missing; // native + classic: TS2339
}

Classic LS (6.0.3)

// getCompletionsAtPosition after `this.`
entries: ['click', 'id']

Native LS

Fourslash VerifyCompletions at the this. marker: Expected completion list but got nil.

Expected behavior

Same as classic / same as a TS this parameter: offer id, click (or HTMLElement members).

Notes

Distinct from documentation API divergence (#64919) and from inlay/signature trailing-rest issues (#65162/#65165).

Activity

  1. timurzvural commented on Nov 3, 2026

    @timurzvural
    Author

    Broader than @this

    Same native LS hole for JSDoc @param types on JS function parameters: checker diagnostics see the type, but hover/completions treat the parameter as any.

    // @allowJs: true
    // @checkJs: true
    /**
     * @param {{ id: string }} p
     */
    function f(p) {
      p./*completions: classic offers id; native nil*/
      p.missing; // both: TS2339 — checker is fine
    }

    Native hover on p: (parameter) p: any
    Classic hover on p: (parameter) p: { id: string; }

    Controls that work on native:

    • TS this / parameter annotations
    • JSDoc @type on const/var with an initializer (or assigned before use)
    • Plain inferred object literals in .js

    So the gap is specifically LS display/completions for types attached via JSDoc to parameters / this, not all JSDoc typing.

  2. changed the title [-]Native LS: no property completions on `this.` when type comes from JSDoc `@this`[/-] [+]Native LS: JSDoc `@this` / `@param` types are `any` for hover & completions (checker OK)[/+] on Nov 3, 2026
  3. timurzvural commented on Nov 3, 2026

    @timurzvural
    Author

    Also signature help

    Call-site signature help for the same JSDoc-@param-typed function shows any parameters on native:

    /**
     * @param {string} a
     * @param {number} b
     */
    function f(a, b) {}
    f(/* signature help here */
    • Classic: f(a: string, b: number): void
    • Native: f(a: any, b: any): void
  4. 1-DARK commented on Nov 4, 2026

    @1-DARK
    Contributor

    Thanks for the detailed report. As far as I can tell this isn't an LS bug; the repro just isn't running in a JS file.

    The fourslash snippets have @allowJs/@checkJs but no // @filename: /something.js, so the content isn't treated as JS. In TS files, JSDoc @this/@param types aren't used for typing, so this/p being any (and no member completions) is expected there.

    With an explicit JS filename, everything in this issue and the follow-up comments already works on native main:

    // @allowJs: true
    // @checkJs: true
    // @filename: /a.js
    /**
     * @this {{ id: string, click: () => void }}
     * @param {{ name: string }} p
     */
    function h(p) {
      this./*→ click, id*/;
      p./*→ name*/;
    }
    /**
     * @param {string} a
     * @param {number} b
     */
    function f(a, b) {}
    f(/*→ f(a: string, b: number): void*/);

    Hover on p shows (parameter) p: { name: string; }. I've added this as a fourslash regression test in #65307. Suggest closing as not a bug; please reopen if you can reproduce it with a real .js file in an editor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScript

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions