4

I am trying to create custom element in jointjs, bu. I don't know how to extend namespaces / interfaces exported by the library so I can easly create a new jointjs element.

The error I am getting is:

Element implicitly has an 'any' type because expression of type '"html"' can't be used to index type 'typeof shapes'. Property 'html' does not exist on type 'typeof shapes'

ERROR > joint.shapes['html'] = {};

import * as joint from 'jointjs';

const BeerObject = (graph: joint.dia.Graph) => {

    joint.shapes['html'] = {};
    joint.shapes['html'].Element = joint.shapes.basic.Rect.extend({
        defaults: joint.util.deepSupplement({
            type: 'html.Element',
            attrs: {
                rect: { stroke: 'none', 'fill-opacity': 0 }
            }
        }, joint.shapes.basic.Rect.prototype.defaults)
    });

};

export default BeerObject;

Playground

1 Answers1

1

Obviously, the error you are getting is because the shapes namespace does not have a property named html (which is exactly what the error message says). Thus, you will have to let the compiler know that the property might exist on the namespace.

To do this, you will need to utilize both module augmentation and namespace merging. This is the basic outline of how it can be done (note that the augmentation must mirror the structure of the library):

declare module "jointjs" {
  export namespace shapes {}
}

Now you need specify that the property html might exist, and that it might have an Element property. Since shapes is a namespace, and you assign to the property at runtime, you can use let to declare it:

declare module "jointjs" {
  export namespace shapes {
    let html: {
      Element?: { /** the type of the custom Element */ }
    } | undefined;
  }
}

And that's it (you can also omit the optionality and | undefined if it suits your use case, of course).

Playground