Issue
Update (2023)
I actually did a talk on how to get tsc
+ JSDoc that answers this question and a few more:
And created a package to help with the tsconfig
boilerplate:
- https://npmjs.org/jswt
npx jswt init
Original Question
I'm trying to use tsc
with plain, Vanilla JS and I'm stumped on how to declare the type a function.
It seems like it should be this simple:
/** @type PersonGreet */
person.greet = function greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
Edit: /** @type PersonGreet */
is correct. The current behavior is a bug in tsc
. The selected answer below gives valid workarounds.
Reduced Test Case
Ignore the fact that someone may want to refactor this into using classes or prototypes or some such - it serves well as a demonstration of the problem.
Repo: https://github.com/BeyondCodeBootcamp/hello-tsc
"use strict";
/**
* @typedef {Object} Person
* @property {String} name
* @property {PersonGreet} greet
*/
/**
* @typedef {Function} PersonGreet
* @param {Person} other
* @returns {String}
*/
let Person = {};
/**
* Creates a person
* @param {Object} p
* @param {String} p.name
* @returns {Person}
*/
Person.create = function (p) {
let person = {};
person.name = p.name;
/////////////////////////////////////////////////////////////////////////////////
//
// error TS7006: Parameter 'other' implicitly has an 'any' type. <======= WRONG!
//
/////////////////////////////////////////////////////////////////////////////////
/** @type PersonGreet */
person.greet = function greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
return person;
};
module.exports = Person;
Incorrectly Typed as "any"
When I run tsc
to check it gives an error about an implicit any:
tsc -p jsconfig.json
person.js:28:33 - error TS7006: Parameter 'other' implicitly has an 'any' type.
28 person.greet = function greet(other) {
~~~~~
Found 1 error in person.js:28
What to do?
To me this seems like a bug in tsc
... but this is JS 101 stuff, surely there must be a way to type a function?
What annotation do I need to use to declare the function's type? Or can tsc
/ tsserver
/ typescript
just not handle this kind of rudimentary use of JS?
Solution
Solution 1
You should use @callback
instead of @function
like so:
"use strict";
/**
* @typedef {Object} Person
* @property {String} name
* @property {PersonGreet} greet
*/
/**
* @callback PersonGreet
* @param {Person} other
* @returns {String}
*/
let Person = {};
/**
* Creates a 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 greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
return person;
};
module.exports = Person;
Solution 2
Or, declare a @typedef
using typescript syntax like the following:
/**
* @typedef {(other: Person) => string} PersonGreet
*/
Answered By - lepsch
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.