Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript newable and enum reference

I have an external SDK written in JavaScript which I am using. One of these modules, Blob is new-able, but also exposes an enum FooEnum (members Bar and Baz).

The code for using this SDK in JavaScript is like so:

const blobInstance = new Sdk.Blob();
const fooType = Sdk.Blob.FooEnum.Baz;

I am now trying to write an interface that I can cast this SDK to in order to give me some type safety. Here is what I've got so far:

interface BlobInterface { }

enum Foo {
    Bar,
    Baz
}

interface Sdk {
    Blob: {
        new(): BlobInterface;
        FooEnum: Foo;
    }
}

My problem, however, is that when I reference Blob.FooEnum, it thinks that FooEnum itself is actually a member of the enum Foo (i.e. it believes that it is Bar or Baz) and, therefore, doesn't let me get Baz from it.

How can I tell TypeScript that Blob.FooEnum actually points to the enum itself and isn't a member of the enum?

like image 548
James Monger Avatar asked Oct 11 '17 15:10

James Monger


1 Answers

Foo is both a value name and a type name. As a value, it represents the object whose properties have keys Bar and Baz and whose values are 0 and 1, respectively (it also has properties with keys 0 and 1 whose values are "Bar" and "Baz", respectively.). As a type, it represents the union of types of Foo.Bar and Foo.Baz. These are not the same: the value Foo is not of type Foo.

This is like in a class (e.g., class Bar {}), where the value Bar represents the class constructor, and the type Bar represents the type of an instance of the class. Again, the value Bar is not of type Bar.

In both cases, if you want the type corresponding to the value with the name Foo or Bar, you use typeof with the value:

interface Sdk {
    Blob: {
        FooEnum: typeof Foo;
    }
}

Now FooEnum has the same type as the object Foo, and it should work for you.

Good luck!

like image 104
jcalz Avatar answered Oct 07 '22 03:10

jcalz