Skip to content

Add simulated nominal type for COM SAFEARRAY and VarDate to lib.scripthost.d.ts #17526

Closed
@zspitz

Description

@zspitz

TypeScript Version: nightly (2.5.0-dev.20170725)

When running Javascript under an Automation context (Windows Script Host, or HTML Applications), there are two types exposed by various APIs: VarDate and SafeArray. These types have no shape from Javascript's perspective:

  • they cannot be constructed using new, and
  • they have no members that can be consumed from Javascript

However, other methods/constructors/properties expect these types and will fail if an incorrect type is passed in:

var rst = new ActiveXObject('ADODB.Recordset');
// open the connection and recordset here
var fields = ['firstname', 'lastname'];
var values = ['Plony', 'Almony'];

// Will fail at runtime, since two SafeArrays are expected, and not two Javascript arrays
rst.Update(fields, values);

Currently, VarDate is typed in lib.scripthost.d.ts as an empty interface; while SafeArray has no defined type, and methods that expect a SafeArray are typed with any (example).

I propose adding a representation of these types to lib.scripthost.d.ts:

declare class VarDate {
    private VarDate_typekey: VarDate;
    private constructor();
}

declare class SafeArray<T = any> {
    private SafeArray_typekey: SafeArray<T>;
    private constructor():
}
  • An interface couldn't be used here, because there is no shape from Javascript, and an empty interface is equivalent to any

  • The private constructor prevents new VarDate();

  • The other private member prevents assigning an arbitrary object to a variable/parameter of this type:

      //compiler error -- Property 'VarDate_typekey' is missing in type '{}'
     let x: VarDate = {};
    

Note that this is actually simulating nominal typing (thanks @Aleksey-Bykov for the suggestion). If some form of nominal typing is introduced to TypeScript, the definitions for VarDate and SafeArray could be rewritten accordingly.


The previous definition for Update could then be written as follows:

declare namespace ADODB {
    interface Recordset {
        Update(Fields: SafeArray<string>, Values: SafeArray): void;
    }
}

VBArray and Enumerator could be modified to take advantage of the generic type of SafeArray, as in this commit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Domain: lib.d.tsThe issue relates to the different libraries shipped with TypeScriptFixedA PR has been merged for this issueHelp WantedYou can do thisSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions