Description
🔎 Search Terms
callback typedef function alias semantic jsdoc tsc tsserver
🕗 Version & Regression Information
Always, up to Version 4.7.4
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about @callback
Summary
You should be able to create a typedef of a Function
and use that type for any applicable function.
For example:
/**
* @typedef {Function} PersonGreet
* @param {String} name - other's name
* @returns {String} - the greeting
*/
/** @type PersonGreet */
let greet = function (name) {
return `Hello ${name}, my name is Rob the Robot!`;
}
However, this fails:
The type of a function declaration must match the function's signature.
Parameter 'name' implicitly has an 'any' type.
Complete Example
⏯ Playground Link
💻 Code
"use strict";
/**
* @typedef {Object} Person
* @property {String} name
* @property {PersonGreet} greet
*/
/**
* @callback PersonGreet
* @param {Person} other
* @returns {String}
*/
let Person = {};
/**
* @param {Object} p
* @param {String} p.name
* @returns {Person}
*/
Person.create = function (p) {
let person = {};
person.name = p.name;
/** @type PersonGreet */
person.greet = function (other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
return person;
};
module.exports = Person;
🙁 Actual behavior
In the example you can see that the checker doesn't apply the type PersonGreet
to the function being assigned to person.greet
.
The type declared with /** @typedef {Function} */
is parsed, but it can't be used to to type a compliant function directly (although it is somewhat usable as an export that other modules can understand the type in some contexts).
🙂 Expected behavior
A type generated with @typedef {Function}
should be able to be applied to functions.
Workaround
There's no documentation for this, but it just so happens that if you use the @callback
alias some extra machinery kicks in and you can type functions as you would have expected.
/**
- * @typedef {Function} PersonGreet
+ * @callback PersonGreet
* @param {String} name - other's name
* @returns {String} - the greeting
*/
/** @type PersonGreet */
let greet = function (name) {
return `Hello ${name}, my name is Rob the Robot!`;
}
The problem is that @callback
is usually incorrect and confusing:
- all functions are functions
- not all functions are callbacks
- in fact, most functions are not callbacks
It's also possible to use TypeScript's proprietary arrow notation, but this generates other errors:
/**
- * @typedef {Function} PersonGreet
- * @param {String} name - other's name
- * @returns {String} - the greeting
+ * @typedef {(
+ * other: Person
+ * ) => string} PersonGreet
*/
/** @type PersonGreet */
let greet = function (name) {
return `Hello ${name}, my name is Rob the Robot!`;
}
JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.