In my Workshop application, I would like to have a bar chart with a changeable x-axis. A dropdown widget would be used to select the desired x-axis.
For this I am writing a TypeScript function, that will return the data that will feed the chart widget.
I have wrote the following function:
@Function()
public async flexibleCounter2DimensionTest(
objects: ObjectSet<Data>,
xaxis : string ): Promise<TwoDimensionalAggregation<string>> {
return objects
.groupBy(val => val[xaxis].topValues())
.count()
}
The xaxis
parameter would define the column name, on which to perform the grouping.
I am struggling to do this in Foundry Functions, I am always receiving the following error on compilation:
{ "stdout": "src/hospital_provider_analysis.ts(170,9): error TS2322: Type 'TwoDimensionalAggregation<BucketKey, number>' is not assignable to type 'TwoDimensionalAggregation<string, number>'.\n Type 'BucketKey' is not assignable to type 'string'.\n Type 'false' is not assignable to type 'string'.\nsrc/hospital_provider_analysis.ts(171,33): error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'BucketableProperties'.\n No index signature with a parameter of type 'string' was found on type 'BucketableProperties'.\n", "stderr": "" }
Any ideas how to fix this issue?
Some of the more powerful parts of Typescript's type-system allow us to specify a type-safe version of this aggregation function. I detail one approach to this in Part 1 below.
When exposing this type-safe aggregation function, we need to perform some additional checks because Functions doesn't currently support union types (see 'Functions API: Input and output types' in your Palantir documentation). I list my code for this in Part 2 below.
First, we list all the property API names that we'd like to group-by as a new union type of literal types. These should be the API names you'd normally use to access these properties in a Function.
type AggregatableStringProperties = "propertyA" | "propertyB" | ...;
Now, we can define a type-safe aggregation function that takes an object set along with which property to aggregated by (of the ones in AggregatableStringProperties
):
private async flexibleCounter2DimensionTestImpl(
objects: ObjectSet<Data>,
xaxis: AggregatableStringProperties,
) : Promise<TwoDimensionalAggregation<string>> {
return objects
.groupBy(val => val[xaxis].topValues())
.count();
}
@Function()
Using the type-safe aggregation function that we defined in Part 1, we can now expose this using type assertions. In the code below, I add some optional logic to provide the user of this Function with helpful debugging information.
@Function()
public async flexibleCounter2DimensionTest(
objects: ObjectSet<Data>,
xaxis : string
): Promise<TwoDimensionalAggregation<string>> {
const xaxis_t = xaxis as AggregatableStringProperties;
if (Data.properties[xaxis_t] === undefined || Data.properties[xaxis_t].baseType.type !== "string") {
throw new UserFacingError("xaxis argument ('" + xaxis + "') is not a string property of the Data object");
}
return this.flexibleCounter2DimensionTestImpl(objects, xaxis_t);
}