#Extend type for different files

1 messages · Page 1 of 1 (latest)

fiery citrus
#

I am working on building plugins for a browser-based application where I'm building a typescript environment to reduce likelihood of breaking the application. For each plugin, I need to define configuration options - there is a based type for config, but each plugin can define their own unique options.

I need something like what I have below, but the problem is that this is affecting all plugins in my repo, not the single plugin I want it to affect. How can I restrict the type to only one plugin? Each plugin is a separate folder.

declare module "@/Type" {
  interface VisionSymbolConfig { // if using this in Plugin A, all is good. But now Plugin B complains that it doesn't implement the interface
    Height: number;
    Width: number;
    FontSize: number;
    LinkText: string;
    NewTab: boolean;
    Color: string;
    TextColor: string;
    BorderColor: string;
  }

  interface VisionScope {
    LinkLocation: string;
    LinkTarget: string;
    LinkText: string;
    getSymbolStyles: () => any;
  }
}
ruby pendant
#

you cant isolate declarations to a specific file/folder

fiery citrus
#

What are the options then? Each plugin makes use of the same base types, but have their own options.

#

I need to reference the base types in other types, which is why I wanted to extend them, but individually for each plugin.

ruby pendant
#

how are you using the plugins? with a function?

fiery citrus
#

No, it's a proprietary application. I build my plugin following their documented conventions, and it works with their application.

#

Example

#

Plugin A has config

getDefaultConfig: function () {
      return {
        DataShape: "Value",
        Height: 40,
        Width: 100,
        FontSize: 14,
        LinkText: "Link Text",
        NewTab: true,
        Color: "rgba(121, 84, 218, 0.85)",
        TextColor: "rgba(255, 255, 255, 1)",
        BorderColor: "rgba(121, 84, 218, 0.85)",
      };
    }
#

Plugin B has config

getDefaultConfig: function () {
      return {
                DataShape: "Table",
                Height: 400,
                Width: 550,
                DeleteValueButtonColor: "rgba(196, 0, 0, 0.77)",
                DeleteValueButtonTextColor: "rgba(255, 255, 255, 1)"
      };
    }
#

DataShape is the only option required by the 3rd party and then there are optional parameters, of which I have not specified any for these 2 plugins. The rest are plugin-specific.

#

But the type that is used for this return function is also used in another interface (the vendor hasn't released any types, I am building them based on functionality)

#

I'd rather have each plugin's specific types, rather than [key: string]: number | string | date

#

I guess I could create interfaces for each plugin. I'd just have to pass them into the base types, whereas in this solution I'm not doing that.

ruby pendant
#

are you accessing these values later or do you want types simply for getDefaultConfig?

fiery citrus
#

They are accessed later, but through a different mechanism.

#

All within the plugin of course. The getDefaultConfig is part of plugin setup. Then there's plugin runtime with a few functions exposed. And those functions contain the configuration (on data update or config changes)

#

Yeah, using generics probably makes more sense in this scenario.

ruby pendant
#

so, just to wrap my head around it, would a plugin look something analagous to this:

export default {
  getDefaultConfig: function () {
    return { foo: 1 }
  }
  someFunc: function (config) {
    doSomething(config.foo)
  }
}
fiery citrus
#

It's browser based. So it's more like

(function (PV: VisionParam) {
  function symbolVis() {}
  PV.deriveVisualizationFromBase(symbolVis);

  // Symbol Definition
  const definition: SymbolDefinition<VisionSymbolConfig> = {
    //.....etc
    typeName: "mi-attribute-link",
    supportsCollections: true,
    getDefaultConfig: function () {
      return {
        DataShape: "Value",
        Height: 40,
        Width: 100
      };
    }
  };

  symbolVis.prototype.init = function (scope: VisionScope, elem: JQuery) {
    this.onDataUpdate = onDataUpdate;
    this.onConfigChange = onConfigChange;
    this.onResize = onResize;

    function onDataUpdate(newData: DataShapeValue) {
      if (!newData) {
        return;
      }

      console.log(newData.Value);
    }

    function onConfigChange(newConfig: VisionSymbolConfig, oldConfig: VisionSymbolConfig) {
      if (newConfig && oldConfig && !angular.equals(newConfig, oldConfig)) {
        ///
      }
  }
})((window as any).PIVisualization);
#

onDataUpdate and onConfigChange both contain variables that have the configuration, and additional plugin-specific parameters.

#

I updated the base classes to be named as such, and used generics for the types, passing in the plugin-specific config type. It's probably the better suited approach