Skip to content

Thinking about typing enum values #32

@jcward

Description

@jcward

I have a first prototype implementation of Enum support (for js-enums-as-arrays) as follows.

Note: these definitions are not sufficient if you wanted to create / instantiate an enum from typescript (e.g. there is no __enum__ parameter), but they're good enough to read the data out of enum values / instances. My purpose is to use a Haxe codebase from TypeScript with usable type definitions - I don't expect TS to generate enum values, but I just want type definitions to use them in a sensible way.

enum Result {
  VALID;
  INVALID(msg:String);
  PENDING(tbd:Promise<Result>)
}

Which (would) generate as follows:

export type Result =
		[ 'VALID', number ] |
		[ 'INVALID', number, /* msg */string ] |
		[ 'PENDING', number, /* tbd */Promise<Result> ]

As you can see (while not entirely pretty), this accurately describes the enum values, and it's sufficient for TS to determine the types of the arguments in a switch-like way, by identifying the first parameter:

image

However, this is not ready to be merged for three reasons.

First, the above generates the following TypeScript error:

Type alias 'Result' circularly references itself.ts(2456)

Checking out the TS repo, I found an issue and a PR for recursive type definitions, but that's very recent. So I had to put in a hack (specifically to support Promise<T> -- you could also support Array<T>, but not T itself.)

Second, my enum declarations are generating in the .d.ts file. While the abstract enums being generated are being put in the enum.ts companion file. In my project, there are both kinds of enums in the same packages, which puts some namespace pkg declarations in the .d.ts file, and some namespace pkg declarations in the .ts file. So then the .d.ts file tries to import { pkg } from enums.ts - the imported namespace collides with the local namespace.

To get around this, I munge both output files into a single .ts file, and change all my export class to export declare class. But there may be a better way...

Third, we should probably detect if the user used Haxe's -D js-enums-as-arrays or not. The above is for the array syntax (which is what my project uses.) But I wonder if it's possible to support the object syntax... I'll think about it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions