Skip to content

Referencing a JSDoc @interface declaration in @param declaration produces an unexpected error flag (JavaScript with TS checks) #55652

Closed
@spillz

Description

@spillz

Does this issue occur when all extensions are disabled?: Yes

Steps to Reproduce:

Here's some sample JavaScript code

//@ts-check

/**
 * @interface Person
 * @property {string} name - The person's name.
 * @property {number} age - The person's age.
 */

/**
 * Greets a person.
 * 
 * @param {Person} person - The person to greet. //VS Code flags this as an error "Cannot find name 'Person'"
 * @returns {string} A greeting message.
 */
function greet(person) {
  return `Hello, ${person.name}! You are ${person.age} years old.`;
}

//Should be a valid call even though occupation is not part of the interface
greet({name:'Joe', age:25, occupation:'miner'});
//Should be an invalid call because age value is wrong type
greet({name:'Joe', age:'X', occupation:'miner'});

I would expect VS Code would flag the second invocation of greet as an error. Instead VS code flags the @param declaration as an error and allows both invocations of greet. Is this expected behavior or an upstream issue? From my reading of various JSDoc discussions, it seems that @interface isn't well supported across the entire ecosystem.

Failing that is the only way to achieve something like this where I can add arbitrary properties to an object as a function parameter that expects the object to have certain properties to use a .d.ts file with the interface definition and include that definition into my JSDoc?

Activity

changed the title [-]Referencing a JSDoc @interface declaration in @param declaration produces an unexpected error flag[/-] [+]Referencing a JSDoc @interface declaration in @param declaration produces an unexpected error flag (JavaScript with TS checks)[/+] on Sep 6, 2023
transferred this issue frommicrosoft/vscodeon Sep 6, 2023
removed their assignment
on Sep 6, 2023
mjbvz

mjbvz commented on Sep 6, 2023

@mjbvz
Contributor

Looks like a duplicate of #41675

spillz

spillz commented on Sep 9, 2023

@spillz
Author

Just for posterity, it's possible to achieve what I need with a typedef rather than an interface. First, if we define the Person as a standard JSdoc @typedef, we can pass extra properties in the object provided it is defined as a named object.

//@ts-check

/**
 * @typedef Person
 * @param {string} name
 * @param {number} age
 */

/**
 * Greets a person.
 * 
 * @param {Person} person - The person to greet.
 * @returns {string} A greeting message.
 */
function greet(person) {
  return `Hello, ${person.name}! You are ${person.age} years old.`;
}

//This is an error because you can't have extraneous properties when passing anonymous objects
greet({name:'Joe', age:25, occupation:'miner'});

//But you can pass a named object with extra properties to the function, so this is OK
let joeObj = {name:'Joe', age:25, occupation:'miner'};
greet(joeObj);

//And this will be invalid because age is the wrong type:
let joeObj2 = {name:'Joe', age:'X', occupation:'miner'};
greet(joeObj2);

But we can go one step better and use a TypeScript type in the JSDoc @typedef with an extra key for arbitrary types and then pass extra properties in the call on the anonymous object as well:

//@ts-check

/**
 * @typedef {{name:string, age:number, [id:string]:any}} Person
 */

/**
 * Greets a person.
 * 
 * @param {Person} person - The person to greet. 
 * @returns {string} A greeting message.
 */
function greet(person) {
  return `Hello, ${person.name}! You are ${person.age} years old.`;
}

//This now works
greet({name:'Joe', age:25, occupation:'miner'});

//And this does not because age is the wrong type
greet({name:'Joe', age:'X', occupation:'miner'});
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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @spillz@mjbvz

        Issue actions

          Referencing a JSDoc @interface declaration in @param declaration produces an unexpected error flag (JavaScript with TS checks) · Issue #55652 · microsoft/TypeScript