GoodData.UI Typings & Type Guards

  • 13 July 2021
  • 0 replies
  • 61 views
GoodData.UI Typings & Type Guards
Userlevel 3

When trying to implement drilling with one of our GoodData.UI visualization components, your compiler or IDE might give you a warning or an error similar to this one:

Property 'attributeHeaderItem' does not exist on type 'DrillEventIntersectionElementHeader'.
  Property 'attributeHeaderItem' does not exist on type 'IAttributeDescriptor'.ts(2339)

What does it mean? And how to fix this? If you're interested, keep reading…

In short, this is a TypeScript warning, and it may pop up even when your project is not in TypeScript and your files have .js extension, as some IDEs read the Typings of dependencies regardless.

TypeScript is a programming language that adds strong typing (that you may know from Python, Ruby, or Java) to otherwise untyped (or loosely typed) JavaScript. It is a strict syntactical superset of JavaScript and adds optional static typing to the language. TypeScript is designed for the development of large applications and transcompiles to JavaScript. As TypeScript is a superset of JavaScript, existing JavaScript programs are also valid TypeScript programs.

GoodData.UI library can be used with both JavaScript and TypeScript projects. Using TypeScript with GoodData.UI is entirely optional, but it is recommended especially for larger projects.

In layman's terms, TypeScript helps us make sure we pass the right props to our GoodData.UI components, and it also checks that we are accessing only legal and existing keys within JSON objects.

So, when we implement drilling by doing something like this:

<AreaChart
measures={[Md.TotalSales]}
viewBy={[Md.Category]}
drillableItems={
[HeaderPredicates.identifierMatch(measureIdentifier(Md.TotalSales))]
}
onDrill={(drillEvent) => {
const selectedCategory = drillEvent.drillContext.intersection[2].header.attributeHeaderItem.name;
handleDrillDown(selectedCategory);
}}
/>

We get the Property 'attributeHeaderItem' does not exist on type 'DrillEventIntersectionElementHeader' message. This is TypeScript telling us that there is no attributeHeaderItem key inside the header object. But how come that the code works then? TypeScript is telling us that the attributeHeaderItem key is not NECESSARILY there, it might be there, and it might not.

As developers, we must assume that the user might have clicked on an element in the chart that does not involve an attribute. Maybe they clicked on a metric that is not sliced by any attributes. If that happened, there is no attributeHeaderItem in the header object, and our application would break. TypeScript here is guarding us against this happening.

So how do we make this right? We will import isDrillIntersectionAttributeItem from @gooddata/sdk-ui and use it as so called TypeScript Type Guard, like this:

<AreaChart
    measures={[Md.TotalSales]}
    viewBy={[Md.Category]}
    drillableItems={
        [HeaderPredicates.identifierMatch(measureIdentifier(Md.TotalSales))]
    }
    onDrill={(drillEvent) => {
        if (isDrillIntersectionAttributeItem(drillEvent.drillContext.intersection[2].header) {
            const selectedCategory = drillEvent.drillContext.intersection[2].header.attributeHeaderItem.name;
            handleDrillDown(selectedCategory);
        }
    }}
/>

Now we made sure that if there's no attribute in the drill intersection, the application won't break, and the attempt to drill will simply fail gracefully instead.

You can read more about TypeScript Type Guards at https://www.typescripttutorial.net/typescript-tutorial/typescript-type-guards/.


0 replies

Be the first to reply!

Reply