Typescript: keyof Enum

Created on 16 Feb 2017  路  4Comments  路  Source: microsoft/TypeScript

Hi,

I ve seen a post over this particular suggestion, but I did not understant why (in typescript, not in js)

why this kind of behavior is not expected on keyof over enum:

enum Kind {
   none,
   bob
}

interface SomeJsonData {
    kind: keyof Kind;
    insteadOfKind: "none" | "bob";
}

Just saying that because it was my first reflex trying keyof over enums out of Partial or Readonly's.
Enum are not part of ecmascript (as I know) so keyof applyed to typescript should have a typescript specific behavior.

I also did not expect keyof returns number values, but if it does, still make more sense than current behavior.

Cheers.

Question

Most helpful comment

Just to clarify, I think that the question is "Why do I get a bunch of string literals named after methods on numbers instead of "none" | "bob". Phrasing the question that way might clarify things a little.

An enum declaration actually declares two types:

  • The type of enum members (e.g. Kind.none, Kind.bob)
  • The type of the enum container itself (i.e. Kind)

Kind.none and Kind.bob each have a base type of Kind, which is really just a subtype of the number type, which has members of the Number type.

Kind on the other hand, is more or less an object with two members on it at runtime. Its type doesn't have a name, but you can still reference it by using the typeof operator (i.e. typeof Kind).

So if you're looking for "none" | "bob", you unfortunately want keyof typeof Kind.

All 4 comments

Just to clarify, I think that the question is "Why do I get a bunch of string literals named after methods on numbers instead of "none" | "bob". Phrasing the question that way might clarify things a little.

An enum declaration actually declares two types:

  • The type of enum members (e.g. Kind.none, Kind.bob)
  • The type of the enum container itself (i.e. Kind)

Kind.none and Kind.bob each have a base type of Kind, which is really just a subtype of the number type, which has members of the Number type.

Kind on the other hand, is more or less an object with two members on it at runtime. Its type doesn't have a name, but you can still reference it by using the typeof operator (i.e. typeof Kind).

So if you're looking for "none" | "bob", you unfortunately want keyof typeof Kind.

This can have credit if:

  • enum where actual types
  • keyof was a real js key world

But, are really expecting this to append when you write keyof Enum ?

As I undertant, one part of your argumentation go again js (no Kind type in js).
But the other part justify the behavior of the keyof over the typescript to js translation.

If you really expect number prototype enumeration when you write that: keyof King... Sorry sir, I think you think weard

This post tell me:
Keyof is a way to enumerate javascript object prototype members but even if enums are object instances, you will not be able to enumerate them that way. Instead of that, has you expected, it will returns the prototype of number, because its making more sense than getting prototype of Object.

@DanielRosenwasser Your answer was very helpful!

However, I get an error using a const enum declaration with your solution.

Is there a workaround for this problem or do I need to submit a feature request?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

weswigham picture weswigham  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

siddjain picture siddjain  路  3Comments

seanzer picture seanzer  路  3Comments

MartynasZilinskas picture MartynasZilinskas  路  3Comments