[Request] Improve pivot table functionality or allow for dynamic interfaces in TS for FunctionsMap output

Hi community,

I’ve been researching and trying some workarounds to this current use case. If you have any suggestions, they are welcome!

This issue could be placed under improvements for pivot tables or as a dynamic interface for returning a FunctionsMap, none of which are currently possible. Consider the following:

1 - An object type for companies, with several numeric properties. Each company, in return, can have a one-to-many link to another object type, which we’ll call departments for the purposes of this example.

2 - In workshop, we need to display aggregates on several fixed categories. Results need to be shown at a company and department level with a custom weighted aggregation logic. Ideally, in the same table/pivot table within a details view.

3 - The values corresponding to each category are stored in a third object type and can be easily obtained by traversing a link.

Methods tried:

a - Pivot table. It (sort of) works, but is not feature complete. We can get the values for each category (row grouping in the pivot table) and set column groupings for the company/department name. This makes impossible to order the columns properly, as they are ordered just by the keys (names), meaning we can only order by company/department name which doesn’t properly reflect the intended hierarchy order.

b - Define a dynamic interface in a TS function. We can have (i) different number of departments associated with each company and (ii) they can be named differently as they serve different purposes. (ii) is especially troublesome, as it can’t be solved by an optional key in the interface definition. We tried to set a dynamic interface such as:

interface Scores {
   [key: string]: Double;
}

to then define a function like this (very simplified for testing purposes):

@Function()
    public async pivotScores(): Promise<FunctionsMap<string, Scores>> {
        let outputMap = new FunctionsMap<string, Scores>();
        let outputinterface: Scores = {
            company1: 1,
            department1: 3,
        }
        return outputMap.set("hello", outputinterface);

    }

which results in the following error:

[error] functions-typescript/src/workflows/… - customTypeIndexInSignature: Type has an index signature i.e { [: string]: }. All properties of an interface need to be declared to be able to use it as a type. Alternatively, use FunctionsMap from “@foundry/functions-api” as the type

Expected behavior would be to be able to use something like:

interface DynamicObject {
  [key: string]: string | number;
}

let userProfile: DynamicObject = {
  name: "John",
  age: 25,
  address: "123 Main St",
};

as the name and amount of departments per company can change between different companies.

Is there a way to make this use case work / a workaround for the error mentioned above?

3 Likes

Hi all, an update on this.

I tried working around the error by pre-defining an interface with all optional keys for all possible keys in this use case (adding ? at the end of the key in the interface).

This works around the error mentioned above, but even if in the function preview I’m able to get the output as intended (only returning the populated keys), when using the function in workshop all keys in the interface are returned, whether they were populated by the function logic or not. Is there a way to solve for this?

Best,

1 Like