Reputation: 20448
At the moment, my example is from the Highcharts library, but I'm asking the general question because I'd like to know how to solve this for any library.
My code snippet is as follows:
tooltip: {
formatter: function () {
return this.series.name + "," + this.point.y;
}
},
I'd like to work out the proper type for 'this'.
I've started by looking at the definition file:
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/highcharts/index.d.ts
The relevant code seems to be as follows:
interface TooltipOptions extends SeriesTooltipOptions {
...
formatter?(): boolean | string;
...
}
Here, I get a little stuck. I've tried modifying the code to:
tooltip: {
formatter: function (this: Highcharts.TooltipOptions) {
return this.series.name + "," + this.point.y;
}
},
but that doesn't work.
What am I doing wrong and how do I work out the correct type?
Upvotes: 8
Views: 2908
Reputation: 41
As already mentioned in another response, you need to first import the correct library for Highcharts.js and then explicitly define the parameter this in the function.
import * as Highcharts from "highcharts";
// other code
const options = {
...
tooltip: {
formatter: function (this: Highcharts.TooltipFormatterContextObject) {
return this.series.name + "," + this.point.y;
}
},
...
}
More Info: https://api.highcharts.com/highcharts/tooltip.formatter
Upvotes: 0
Reputation: 9706
Highcharts exports the types you need. Just do the following:
import Highcharts from 'highcharts`;
...
tooltip: {
formatter(this: Highcharts.TooltipFormatterContextObject) {
// your code
}
}
Upvotes: 9
Reputation: 2857
The problem with working out the type of this with these function calls is that the third-party api can bind whatever object it wants to it.
tooltip.formatter.bind(someHighChartsObject);
tooltip.formatter(); // this refers to someHighChartsObject
tooltip.formatter.bind(someOtherHighChartsObject);
tooltip.formatter(); // this refers to someOtherHighChartsObject
Inside of the function, it's a bit difficult to specify the type of this as it could be anything including one not defined by their documentation. In your specific case, it should be of type Highcharts.PointObject
or Highcharts.ChartObject
which you could technically specify with the following:
const that: Highcharts.PointObject = this;
that.series.name;
Issues:
this
so you're cloning the object just to get stronger typing.this
and write your own interface.TL;DR
It's not possible to simply add in stronger typing to the this
object in an function that is called by third-party code.
Upvotes: 1
Reputation: 30959
Fortunately, this documentation comment has a list of all the members that are guaranteed to exist on this
. (If there were no documentation, you could always console.log(this)
from your function and look at what's there.) In essence, you'd have to write a TypeScript interface that declares all of the members with the proper types:
interface TooltipFormatterContext {
percentage: number; // Is this correct?
// ...
}
and then use this interface as your this
type. If you want to properly represent shared vs. non-shared tooltips, you'd need two different interfaces similar to the current TooltipOptions
that fix shared
to false
and true
respectively and have the corresponding this
types for the formatter, and then you'd define TooltipOptions
as a union type of the two interfaces.
Upvotes: 0