Say I have following definition:
interface Options<T = any, K = void> {
scope?: K,
success: (this: K, result: T) => any,
failure: (this: K, result: T) => any
}
interface HttpClient {
request<T>(opts: Options<T>)
}
From above definition, typescript wont give me correct type for this in success
& failure
. How do I tell Typescript
that K should be scope
property of the first argument.
Example usage:
class Abc {
//...
save() {
var client = new HttpClient()
client.request({
scope: this,
success: function(result) {
this // here no intellisense
}
})
}
notify(event, data) {
this.element.dispatchEvent(new CustomEvent(event, { detail: data }));
}
}
When you declare request<T>(opts: Options<T>)
you are fixing the type K
with its default value void
. If you want to keep that type variable as something variable it must still be a type parameter in request<T,K>
.
This code correctly deduces the type of this
as this
:
interface Options<T = any, K = void> {
scope?: K,
success: (this: K, result: T) => any,
failure?: (this: K, result: T) => any
}
class HttpClient {
request<T, K>(opts: Options<T, K>) : any {}
}
class Abc {
//...
save() {
var client = new HttpClient()
client.request({
scope: this,
success: function(result) {
this // here intellisense offers `notify` and `save` completion
}
})
}
notify(event, data) {
this.element.dispatchEvent(new CustomEvent(event, { detail: data }));
}
}
Other minor code changes: I had to make failure
optional and HttpClient
a class just for the purposes of getting some code that doesn't complain about anything higher up than notify()
.