microsoft/TypeScript

Include const enum members as possible literal types

dead-claudia opened this issue · 5 comments

String literals are already valid types now. This is very nice, but I would like the ability to use const enum members to the same effect. They don't change, they take a lot less memory, and they're faster to check. Plus, you have a clearer distinction of what the type is, where strings are pretty free-form at times.

// Now
type NodeType = "start" | "end"; // etc.
interface Node {
  type: NodeType;
}

interface StartNode {
  type: "start";
}

// What I'd like:
const enum NodeType {
  Start,
  End,
  // etc.
}

interface Node {
  type: NodeType;
}

interface StartNode {
  type: NodeType.Start;
}

Good idea to create an issue for this (following up from #1003 (comment) and #1003 (comment)).

I had an experimental version of this working with widening. I don't think that will actually work (due to problems surfacing from best-common type checking), so the way this would work is contextually typing. @mhegazy and I spoke offline about this the other day.

The point at which we decide to check for a contextual type is the question here. I don't necessarily want to resolve twice to try to grab an enum member type, but in practice, the perf impact from string literal type checking was not even much.

I have a version of this (enum member types) running with contextual typing built on top of my numeric literal PR, but I was having issues determining sane compatibility rules with numbers and numeric literal types without a separate comparable relationship. Now that strict null checking and the comparable relationship have been merged, I should update it to see how well it works.

@DanielRosenwasser What about memory? That's my other concern. Scalability and memory are why I filed this bug. (If you're dealing with a lot of ADT types, it helps.)

With #9407 const enum members become literal types.

#9407 has been merged, closing this issue.