-
Notifications
You must be signed in to change notification settings - Fork 1
Description
I found that there is indeed a super easy way of creating a typed wrapper. I think we should consider this.
This is the wrapper function we want to write for NPM anyway, only slightly modified to integrate methodName and methodOptions into one parameter:
function wrapPerformAssp(
inputFilename: string,
outputFilename: string,
methodNameAndOptions: AsspMethodNameAndOptions,
outputFormat: "TSV" | "SSFF")
{
const api = {
performAssp: Module.cwrap(
'performAssp',
'number',
['string', 'string', 'string', 'string', 'string']
);
};
api.performAssp(
inputFilename,
outputFilename,
methodNameAndOptions.name,
JSON.stringify(methodNameAndOptions.options),
outputFormat
);
}Then we only need a type definition for each of the ASSP methods (forest, rmsana, ...), but no method-specific function body is required. Everything is handled by the above wrapPerformAssp. The type definitions look like this:
interface ForestOptionsObject {
beginTime?: number;
endTime?: number;
effectiveLength?: boolean;
windowSize?: number;
gender?: "m" | "f";
};
interface RmsAnaOptionsObject {
beginTime?: number;
centerTime?: number;
endTime?: number;
linear?: boolean;
};
type AsspMethodNameAndOptions = {
name: "forest";
options: ForestOptionsObject;
} | {
name: "rmsAna";
options: RmsAnaOptionsObject;
};Now the caller is type safe:
let foo: AsspMethodNameAndOptions = {
name: "forest",
options: {
beginTime: 2,
endTime: 1,
linear: true
}
};
wrapPerformAssp("input", "output", foo, "TSV");This does not compile because I used an rmsana option (linear) but called forest. The compiler error looks like this, which imo is extremely helpful:
> tsc main.ts
main.ts:64:13 - error TS2326: Types of property 'options' are incompatible.
Type '{ beginTime: number; endTime: number; linear: boolean; }' is not assignable to type 'ForestOptionsObject'.
Object literal may only specify known properties, and 'linear' does not exist in type 'ForestOptionsObject'.
64 linear: true
~~~~~~~~~~~~
Found 1 error.
Problem
The only problem I see is that the required type definitions duplicate the method-specific option lists from https://github.com/IPS-LMU/wasmassp/blob/master/performAssp.c. That’s 10 methods with a total of about 130 options – which translates to about 200 lines of Typescript definitions.
But I really think this is worth the trouble.
To avoid any problems with future changes to method or option names (remember though that they haven’t changed in at least six years and most likely even longer), we could include a unit-test-like shell script that compares performAssp.c and the Typescript definitions file in this respect and rings an alarm if there is a mismatch.