Skip to content

Possible typed version of wrapper function #1

@MJochim

Description

@MJochim

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions