englercj / tsd-jsdoc

Compiles JSDoc annotated JavaScript into a Typescript Definition file (.d.ts)
MIT License
316 stars 42 forks source link

Syntax to get `this: this` into typings for function? #138

Open thw0rted opened 4 years ago

thw0rted commented 4 years ago

I'm trying to wind up with the following Typescript

class Event<T extends Function> {
  addListener(cb: T);
}
class Base {
  foo: string;
  evt: Event<(this: this, arg: number) => void>;
}

My first impulse was

/**
 * @callback Base.Callback
 * @this Base
 */
class Base {
/**
 * @type {Event<Base.Callback>}
 */
  evt = ...;
}

but that gives me Event<(this: Base, arg: number) => void>, which means that this won't work:

class Sub extends Base {
  bar: number;
}
const s = new Sub();
s.evt = function(arg) {
  this.bar = 4;
}

I tried values of the @this tag like "this" or "Base.this". The former makes bad typings, because the callback is defined in a merged namespace Base, so this doesn't exist there. The latter isn't valid syntax. I also tried just shoving the actual Typescript into the @type tag, with no @callback at all, but the JSDoc parser trips over @type {Event<(this: this, arg: number) => void}>.

thw0rted commented 4 years ago

Update: I tried the Closure syntax for this-type. @type {Event<function(this:this)>} doesn't choke JSDoc, at least. The bad news is that this emits in tsd-jsdoc as Event<(arg0: this, arg1: this) => void>. It looks like the : is being treated as a , or something?

Closure also specifies function(new: Foo) but tsd-jsdoc turns that into the invalid emit (arg0: new () => , arg1: Foo) => void -- note the function arrow with an empty space where the return type would be. Something's weird with handling colons inside of function(...) in a type context.

englercj commented 4 years ago

Have you tried @this

Sorry missed the second half of your post. Looks like we should just add support to our @this handling for the syntax @this this. PRs welcome.