3

Closed

declaring callback scope members

description

Many JavaScript libraries have a usage pattern where you call a method and pass a callback, and later it gets called with both argument and a custom scope for this (eg: via Function.call() or apply()).

This is a sneaky way to pass implicit state while keeping the signature clean. It is arguable not ideal but it is used in many popular libraries so we'd like to be able to describe this.

Simple examples:
Vue.directive('my-directive', function (value: any) {
    this.el.innerHTML = 'foo: ' + this.id;
    // ...
});
oboe(url)
    .node('!foo', function (value) {
        if (value == bad) {
            this.abort();
        }
        // ...
    })
In case of the first snippet you could have something like:
declare module Vue {
    function directive: (name: string, callback: DirectiveCallback): void;
}
interface DirectiveCallback {
    (value: any): void # {
        id: string;
        el: DOMElement;
    }
}
// or split it up:
interface DirectiveCallback {
    (value: any): void $ DirectiveCallbackScope;
}
interface DirectiveCallbackScope {
    id: string;
    el: DOMElement;
}
It uses the callable signature with a interface body (with a prefix maybe, like # or $ to break pattern and make it explicit the this is about the this scope).
This would work for any callable signature declaration. (interface member, callable-interface, module function and variable or return types etc).
Closed Jul 28, 2014 at 10:18 PM by jonturner
As part of our move to GitHub, we're closing our CodePlex suggestions and asking that people move them to the GitHub issue tracker for further discussion. Some feature requests may already be active on GitHub, so please make sure to look for an existing issue before filing a new one.

You can find our GitHub issue tracker here:
https://github.com/microsoft/typeScript/issues

comments

jamesnw wrote Apr 3, 2014 at 9:54 PM

I think this may be solved via this issue: (no pun intended! LOL)
https://typescript.codeplex.com/workitem/507

Bartvds wrote Apr 3, 2014 at 10:24 PM

Hah, this is exactly what I meant!

So this is a duplicate: let's close it (but I cannot close my own tickets so somebody else needs to do it)