---
title: "TypeScript Generics"
framework: vue
version: "14.1.0"
---

# TypeScript Generics

AG Charts leverages TypeScript Generics for chart data and context. This significantly enhances the developer experience through improved code completion and compile-time validation.

## Type <TDatum>

The `TDatum` (default: `any`) generic parameter is used to specify the interface of datums in the data.

#### TDatum Generic Parameter

```ts
import { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
} from "ag-charts-community";

type MyDatumType = {
  country: string;
  gdp: number;
  region: "AMER" | "APAC" | "EMEA";
};

function unreachable(_arg) {
  throw new Error();
}

ModuleRegistry.registerModules([
  BarSeriesModule,
  CategoryAxisModule,
  LegendModule,
  NumberAxisModule,
]);

const ChartExample = defineComponent({
  template: `
    <ag-charts
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<AgChartOptions<MyDatumType>>({
      title: {
        text: "Country GDP by region (in USD)",
      },
      data: [
        { region: "AMER", country: "Brazil", gdp: 2200 },
        { region: "AMER", country: "Canada", gdp: 2000 },
        { region: "AMER", country: "United States", gdp: 25000 },
        { region: "APAC", country: "China", gdp: 17000 },
        { region: "APAC", country: "India", gdp: 3400 },
        { region: "APAC", country: "Japan", gdp: 5000 },
        { region: "EMEA", country: "France", gdp: 3000 },
        { region: "EMEA", country: "Germany", gdp: 4000 },
        { region: "EMEA", country: "South Africa", gdp: 900 },
        { region: "EMEA", country: "United Kingdom", gdp: 3200 },
      ],
      series: [
        {
          type: "bar",
          yKey: "gdp",
          xKey: "country",
          itemStyler: (params) => {
            switch (params.datum.region) {
              case "AMER":
                return { fill: "red" };
              case "APAC":
                return { fill: "blue" };
              case "EMEA":
                return { fill: "green" };
              default:
                unreachable(params.datum.region);
            }
          },
        },
      ],
    });

    return {
      options,
    };
  },
});

createApp(ChartExample).mount("#app");
```

[Live example: TDatum Generic Parameter](https://www.ag-grid.com/charts/vue3/ts-generics/examples/type-tdatum)

```ts
type MyDatumType = {
    country: string;
    gdp: number;
    region: 'AMER' | 'APAC' | 'EMEA';
};

const options: AgChartOptions<MyDatumType> = {
    data: [
        { region: 'AMER', country: 'Brazil', gdp: 2200 },
        { region: 'AMER', country: 'Canada', gdp: 2000 },
        { region: 'AMER', country: 'United States', gdp: 25000 },
        { region: 'APAC', country: 'China', gdp: 17000 },
        { region: 'APAC', country: 'India', gdp: 3400 },
        { region: 'APAC', country: 'Japan', gdp: 5000 },
        { region: 'EMEA', country: 'France', gdp: 3000 },
        { region: 'EMEA', country: 'Germany', gdp: 4000 },
        { region: 'EMEA', country: 'South Africa', gdp: 900 },
        { region: 'EMEA', country: 'United Kingdom', gdp: 3200 },
    ],
    series: [
        {
            type: 'bar',
            yKey: 'gdp',
            xKey: 'country',
            itemStyler: (params) => {
                switch (params.datum.region) {
                    case 'AMER':
                        return { fill: 'red' };
                    case 'APAC':
                        return { fill: 'blue' };
                    case 'EMEA':
                        return { fill: 'green' };
                    default:
                        // (unreachable code)
                        throw new Error();
                }
            },
        },
    ],
    /* ... */
};
```

In this example, specifying the `TDatum = MyDatumType` generic parameter does the following:

- Enables compile-time checks & auto-complete for the elements of the `data[]` property.
- Enforces type-safety for the `series[].xKey` and `series[].yKey`. These properties must be keys of the `MyDatumType` type.
- Automatically infers the type of `params.datum.region` in the `itemStyler` callback.

## Type <TContext>

The `TContext` type (default: `unknown`) generic parameter is used to specify the interface of the `context` properties.

The [Context Object](https://www.ag-grid.com/charts/vue/context/) is arbitrary user-defined data that will be passed to all callbacks. This is useful for attaching custom state to your chart.

#### TContext Generic Parameter

```ts
import { createApp, defineComponent, ref } from "vue";
import { AgCharts } from "ag-charts-vue3";
import type { AgChartOptions } from "ag-charts-types";
import {
  AnimationModule,
  CandlestickSeriesModule,
  ContextMenuModule,
  CrosshairModule,
  LegendModule,
  ModuleRegistry,
  NumberAxisModule,
  TimeAxisModule,
} from "ag-charts-enterprise";
import { makeCurrencyConverter } from "./currencyConverter";
import { getData } from "./data";
import clone from "clone";

ModuleRegistry.registerModules([
  AnimationModule,
  CandlestickSeriesModule,
  ContextMenuModule,
  CrosshairModule,
  LegendModule,
  NumberAxisModule,
  TimeAxisModule,
]);

const ChartExample = defineComponent({
  template: `
    <div class="example-controls">
      <div class="controls-row">
        <label for="mySelect">User Currency: </label>
        <select id="mySelect" v-on:change="onMySelectChange($event.target.value)">
          <option value="EUR">🇪🇺 Euros (€)</option>
          <option value="USD">🇺🇸 US Dollars ($)</option>
          <option value="GBP">🇬🇧 Sterling Pound (£)</option>
          <option value="JPY">🇯🇵 Japanese Yen (¥)</option>
          <option value="INR">🇮🇳 Indian Rupee (₹)</option>
        </select>
      </div>
    </div>
    <ag-charts
      :options="options"
    />
  `,
  components: {
    "ag-charts": AgCharts,
  },
  setup(props) {
    const options = ref<AgCartesianChartOptions<TradeDatum, CurrencyConverter>>(
      {
        context: makeCurrencyConverter("EUR"),
        title: {
          text: "Stock Prices",
        },
        data: getData(),
        series: [
          {
            type: "candlestick",
            xKey: "date",
            openKey: "open",
            highKey: "high",
            lowKey: "low",
            closeKey: "close",
            tooltip: {
              renderer: ({ datum, context }) => {
                if (context == null) return {};
                return {
                  title: datum.date.toDateString(),
                  data: [
                    {
                      label: "Open",
                      value: context.formatBothCurrencies(datum.open),
                    },
                    {
                      label: "High",
                      value: context.formatBothCurrencies(datum.high),
                    },
                    {
                      label: "Low",
                      value: context.formatBothCurrencies(datum.low),
                    },
                    {
                      label: "Close",
                      value: context.formatBothCurrencies(datum.close),
                    },
                  ],
                };
              },
            },
          },
        ],
        axes: {
          x: {
            type: "time",
          },
          y: {
            type: "number",
            label: {
              formatter: ({ value, context }) => {
                return context?.formatUserCurrency(value);
              },
            },
          },
        },
        contextMenu: {
          items: [
            {
              showOn: "series-node",
              label: "Log as USD",
              action: ({ datum, context }) =>
                console.log(context?.formatLog(datum, "USD")),
            },
            {
              showOn: "series-node",
              label: "Log as EUR",
              action: ({ datum, context }) =>
                console.log(context?.formatLog(datum, "EUR")),
            },
            {
              showOn: "series-node",
              label: "Log as GBP",
              action: ({ datum, context }) =>
                console.log(context?.formatLog(datum, "GBP")),
            },
            {
              showOn: "series-node",
              label: "Log as JPY",
              action: ({ datum, context }) =>
                console.log(context?.formatLog(datum, "JPY")),
            },
            {
              showOn: "series-node",
              label: "Log as INR",
              action: ({ datum, context }) =>
                console.log(context?.formatLog(datum, "INR")),
            },
          ],
        },
      },
    );

    const onMySelectChange = (value) => {
      const optionsCopy = clone(options.value);

      optionsCopy.context = makeCurrencyConverter(value);

      options.value = optionsCopy;
    };

    return {
      options,
      onMySelectChange,
    };
  },
});

createApp(ChartExample).mount("#app");
```

[Live example: TContext Generic Parameter](https://www.ag-grid.com/charts/vue3/ts-generics/examples/type-tcontext)

In this example the `TContext` generic parameter is set to a `CurrencyConverter` object to convert stock prices from USD to a user-defined target currency.

This is used by:

- The Y-axis [Label Formatter](https://www.ag-grid.com/charts/vue/axes-labels/#formatter), to convert USD values to the preferred User Currency.
- The [Tooltip Renderer](https://www.ag-grid.com/charts/vue/tooltips/#modifying-content), to render both the stock prices in USD and the User Currency (if applicable).
- The [Context Menu Actions](https://www.ag-grid.com/charts/vue/context-menu/#custom-actions), to log converted stock prices to the console.
