TypeScript: JsDoc annotations don't play well with arguments destructuring

Code

As stated in this comment (I am afraid this won’t be seen since the issue is closed, hence the issue):

/**
 * @param {Object} args 
 * @param {string} args.prop1
 * @param {string} args.prop2
 */
function patate({ prop1, prop2 }) {

}

Expected behavior:

Type-checking this using --allowJs and --checkJs shouldn’t result in an error but rather apply the right type-annotations to the both properties.

Actual behavior: The compiler raises the following error:

error TS8024: JSDoc '@param' tag has name 'args', but there is no parameter with that name.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 6
  • Comments: 17 (5 by maintainers)

Most upvoted comments

@KtorZ

There is a workaround which we are using in our project. I don’t really know if it works for you, as the following approach can’t be used with function declarations, but anyway:

/**
 * @type {function({prop1: string, prop2: string}): void}
 */
const patate = ({prop1, prop2}) => {
    // ...
}

/**
 * This definition works as well.
 * @type {(args: {prop1: string, prop2: string}) => void}
 */
const patate = ({prop1, prop2}) => {
    // ...
}

It’s certainly not as legible as describing every property in it’s own @param annotation, though you can move object’s definition to its own @typedef.

And there is one major pitfall of which you should know. TypeScript currently has a bug (#22080) which allows to invoke former function without any arguments:

/**
 * @type {function({prop: string}): void}
 */
const func = ({prop}) => {
    // ...
};

// TypeScript should raise an error for the following
// line ('Expect 1 argument, but got 0'), but unfortunately it doesn't. 
func();

I hope it helps.

We definitely need this. If I can help somehow let me know guys.

Thanks. For now I’ve been simply doing the destructuring in the function body and it works fine, though I’d rather cut off this extra line… Perhaps I can apply your solution in some cases 😕

/**
 * @param {Object} args 
 * @param {string} args.prop1
 * @param {string} args.prop2
 */
function patate(args) {
  const { prop1, prop2 } = args;
}