Skip to content

Fix grammar checks for modifiers on @template type parameters#4077

Closed
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-template-modifier-errors
Closed

Fix grammar checks for modifiers on @template type parameters#4077
Copilot wants to merge 3 commits into
mainfrom
copilot/fix-template-modifier-errors

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 29, 2026

Grammar checks for in/out/const modifiers on type parameters in JSDoc @template tags were not resolving the effective parent declaration, causing spurious TS1274 errors like:

/**
 * @template out T
 *            ~~~
 * error TS1274: 'out' modifier can only appear on a type parameter of a class, interface or type alias
 * @typedef {Object} Covariant
 * @property {T} x
 */

Changes

  • Resolve JSDoc host for const modifier — when a type parameter is inside a @template tag, look up the effective host declaration (function/class) instead of using the template tag as the parent
  • Resolve JSDoc host or @typedef for in/out modifiers — same as above, with fallback to finding a @typedef tag in the same JSDoc block (which acts as a type alias)
  • Fix isJSDocTypedefTag — was unconditionally returning false (stubbed with // !!!)
  • Use IsTypeOrJSTypeAliasDeclaration — the existing check used IsTypeAliasDeclaration which doesn't match KindJSTypeAliasDeclaration (the reparsed typedef nodes)

Port the logic from TypeScript's checker to properly resolve the parent
declaration for type parameters defined in JSDoc @template tags.

For the `const` modifier, resolve the effective JSDoc host to allow
const type parameters on function/method/class declarations annotated
via JSDoc.

For the `in`/`out` modifiers, resolve the effective JSDoc host or find
a @typedef tag in the same JSDoc block to allow variance annotations
on type parameters of type aliases defined via @typedef.

Also fix:
- isJSDocTypedefTag to actually check the node kind
- Use IsTypeOrJSTypeAliasDeclaration instead of IsTypeAliasDeclaration
  to properly handle reparsed JSTypeAliasDeclaration nodes

Fixes #1299

Co-authored-by: DanielRosenwasser <972891+DanielRosenwasser@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix unexpected errors for modifiers on @template type parameters Fix grammar checks for modifiers on @template type parameters May 29, 2026
Copilot AI requested a review from DanielRosenwasser May 29, 2026 23:49
Comment thread internal/checker/grammarchecks.go
@DanielRosenwasser DanielRosenwasser marked this pull request as ready for review May 30, 2026 00:20
Copilot AI review requested due to automatic review settings May 30, 2026 00:20
Copy link
Copy Markdown
Member

@DanielRosenwasser DanielRosenwasser left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Un)surprisingly, it seems like we have no tests for in/out modifiers when @template parameters are used on classes (maybe we had coverage for function-declared classes a while back).

Since we are now fiddling with logic to find host nodes, we need to make sure we don't regress.

Let's add a compiler test for this

// @checkJs: true
// @Filename: /index.js
/** @template in T */
export class Consumer {
    /** @param {T} value */
    eat(value) {
    }
}

export class Food {
    /** @readonly */ isFood = true;
}

export class Vegetable extends Food {
    /** @readonly */ isVegetables = true;
}

export class Meat extends Food {
    /** @readonly */ isMeat = true;
}

/** @param {Consumer<Food>} omnivore */
export function feed(omnivore) {
    omnivore.eat(new Meat());
}

/** @type {Consumer<Vegetable>} */
let vegetarian = new Consumer();

feed(vegetarian);

Also, this test which validates calculation of in/out

/** @template in T */
export class Producer {
    make(): T {
        throw new Error("Not implemented");
    }
}

/** @template in out T */
export class Consumer {
    /** @param {T} value */
    take = (value) => {}
}

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Copy Markdown
Member

@ahejlsberg ahejlsberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this PR are overly complicated. With reparsing there's no reason to look for JSDoc hosts and walk around in the AST. All we need is to permit JSTypeAliasDeclaration parents for type parameters when checking in and out modifiers. I will put up a simpler PR.

@jakebailey jakebailey closed this May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unexpected errors for modifiers on @template type parameters

5 participants