Support for this was added in TypeScript 2.9 as part of expanded key support mapped types. Specifically:

A mapped type { [P in K]: XXX } permits any K assignable to string | number | symbol.

That means you can make a type alias to a mapped type with enum values as the key:

enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

type MyEnumValuedKeys = { [K in MyEnum]: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1": boolean;
//  "prop 2": boolean;
//  ... more props
// }

You can make mapped type properties optional by adding a ? after the index-like key:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1"?: boolean;
//  "prop 2"?: boolean;
//  ... more props
// }

So you can use OptionalMyEnumValuedKeys as your PropertyInterface. It is a type alias and not an interface. That usually doesn't matter but in case it does, TypeScript 2.8 introduced the abilitity to extend certain concrete mapped types, so you can get an interface like this:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; };
interface PropertyInterface extends OptionalMyEnumValuedKeys {} // add no properties

This could also be accomplished by using the built-in Record and Partial type aliases:

interface PropertyInterface extends Partial<Record<MyEnum, boolean>> {}

Okay, hope that helps. Good luck!

Answer from jcalz on Stack Overflow
🌐
GitHub
github.com › Microsoft › TypeScript › issues › 16687
Using const string enum as object key produces an indexed type · Issue #16687 · microsoft/TypeScript
June 22, 2017 - CommittedThe team has roadmapped this issueThe team has roadmapped this issueFixedA PR has been merged for this issueA PR has been merged for this issueSuggestionAn idea for TypeScriptAn idea for TypeScript ... const enum Test { A = 'a', B = 'b' } type TestMap = {[key in Test]: string} // Type ...
Author   Jessidhia
🌐
GitHub
github.com › microsoft › TypeScript › issues › 22892
Using string enum as key in {[key]: Type} throws not an index signature · Issue #22892 · microsoft/TypeScript
March 26, 2018 - TypeScript Version: 2.9.0-dev.20180325 · Search Terms: string enum index signature cast · Code · enum Fruits { MANGO = 'MANGO', BANANA = 'BANANA', } type StringDict = { [key: string]: string }; function map(dict: StringDict, transform: (key: string, value: string) => void) { const result = {}; for (const key of Object.keys(dict)) { result[key] = transform(key, dict[key]); } return result; } map(Fruits, (key, value) => { value.toLowerCase(); }); map(Fruits as StringDict, (key, value) => { value.toLowerCase(); }); Expected behavior: Both map calls succeed, because a string enum is essentially a {[key: string]: string}. I ought to be able to use it anywhere that needs something indexed by string (as long as the values are appropriate).
Author   appsforartists
Discussions

Allow enums as object literal keys
There was an error while loading. Please reload this page · TypeScript Version: 2.5.3 More on github.com
🌐 github.com
2
October 19, 2017
TypeScript: typings based on object keys that come from enum - Stack Overflow
I have an enum. I'd like to use its values to create typings for an object where these values became keys. The following example demonstrates what I'd like to achieve: export enum MyEnum { PROP_... More on stackoverflow.com
🌐 stackoverflow.com
typescript - Use enum as restricted key type - Stack Overflow
The question here is "how to limit the keys to be of an Enum". Yours is different I believe. Yet, as a wild guess, either Partial should work for you or Partial> | { yyy?: string}, maybe. 2020-12-05T10:43:45.577Z+00:00 ... Nice one but the problem with this solution is that number can be undefined 2021-06-04T15:47:51.03Z+00:00 ... @walox Typescript had a problem distinguishing undefined and missing/optional -- see github... More on stackoverflow.com
🌐 stackoverflow.com
May 29, 2017
Enum From Object Literal Keys
As discussed in other issues in this repo, it is not trivial to create an enum from an object literal keys, or even from an array of strings: (Argument of type 'K[]' is not assignable to pa... More on github.com
🌐 github.com
6
2
🌐
GitHub
github.com › nfriend › ts-key-enum
GitHub - nfriend/ts-key-enum: A TypeScript string enum for compile-time safety when working with event.key
The enum does not contain values for printable keys such as "a", "A", "#", "é", or "¿", simply because the list of possible values is too vast to include in a single enum. To test for printable values, simply use a string comparison: ... This package is published as two versions on NPM: v2.x and v3.x. ... The end result is a JavaScript object that contains every enum value.
Starred by 118 users
Forked by 6 users
Languages   TypeScript 86.5% | Shell 13.5% | TypeScript 86.5% | Shell 13.5%
🌐
TypeScript
typescriptlang.org › docs › handbook › enums.html
TypeScript: Handbook - Enums
Even though Enums are real objects that exist at runtime, the keyof keyword works differently than you might expect for typical objects. Instead, use keyof typeof to get a Type that represents all Enum keys as strings.
🌐
GitHub
github.com › dphilipson › typescript-string-enums
GitHub - dphilipson/typescript-string-enums: Typesafe string enums in TypeScript pre-2.4.
When passing in an arbitrary key to the object from the previous step, we get a value which might be any one of the object's values, and so its type is thus the union of the types of the object's values. Hence, Enum<typeof Enum("RUNNING", "STOPPED")> evaluates to "RUNNING" | "STOPPED", which is what we want. With the addition of native string enums in TypeScript ...
Starred by 82 users
Forked by 3 users
Languages   TypeScript 100.0% | TypeScript 100.0%
🌐
GitHub
github.com › microsoft › TypeScript › issues › 19332
Allow enums as object literal keys · Issue #19332 · microsoft/TypeScript
October 19, 2017 - TypeScript Version: 2.5.3 Code enum SomeValues { first, second, } interface SomeInterface { [key: SomeValues]: string; //
Author   aminpaks
Top answer
1 of 2
74

Support for this was added in TypeScript 2.9 as part of expanded key support mapped types. Specifically:

A mapped type { [P in K]: XXX } permits any K assignable to string | number | symbol.

That means you can make a type alias to a mapped type with enum values as the key:

enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

type MyEnumValuedKeys = { [K in MyEnum]: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1": boolean;
//  "prop 2": boolean;
//  ... more props
// }

You can make mapped type properties optional by adding a ? after the index-like key:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; }
// identical to 
// type MyEnumValuedKeys = {
//  "prop 1"?: boolean;
//  "prop 2"?: boolean;
//  ... more props
// }

So you can use OptionalMyEnumValuedKeys as your PropertyInterface. It is a type alias and not an interface. That usually doesn't matter but in case it does, TypeScript 2.8 introduced the abilitity to extend certain concrete mapped types, so you can get an interface like this:

type OptionalMyEnumValuedKeys = { [K in MyEnum]?: boolean; };
interface PropertyInterface extends OptionalMyEnumValuedKeys {} // add no properties

This could also be accomplished by using the built-in Record and Partial type aliases:

interface PropertyInterface extends Partial<Record<MyEnum, boolean>> {}

Okay, hope that helps. Good luck!

2 of 2
5

It's been a long time since asked, but if you end up here this may be what you're after:

enum MyEnum {
  PROP_1 = "prop 1",
  PROP_2 = "prop 2",
  // ... more props
}

interface MyInterface {
  property: {
    [MyEnum.PROP_1]: boolean,
    [MyEnum.PROP_2]: boolean,
    // ... more props
  }
}

Source: https://github.com/Microsoft/TypeScript/issues/14682#issuecomment-286999967

Top answer
1 of 6
445

Since 2018, there is an easier way in Typescript, without using keyof typeof:

let obj: { [key in MyEnum]: any} =
 { [MyEnum.First]: 1, [MyEnum.Second]: 2 };

To not have to include all keys:

let obj: { [key in MyEnum]?: any} =
 { [MyEnum.First]: 1 };

To know the difference between in and keyof typeof, continue reading.


in Enum vs keyof typeof Enum

in Enum compiles to enum values and keyof typeof to enum keys.


Other differences

With keyof typeof, you cannot change the enum properties:

let obj: { [key in keyof typeof MyEnum]?: any} = { First: 1 };
obj.First = 1;
// Cannot assign to 'First' because it is a read-only property.

... unless you use -readonly:

let obj: { -readonly [key in keyof typeof MyEnum]?: any} = { First: 1 };
obj.First = 1; // works

But you can use any integer key?!:

let obj: { [key in keyof typeof MyEnum]?: any} = { First: 1 };
obj[2] = 1;

keyof typeof will compile to:

{
    [x: number]: any;
    readonly First?: any;
    readonly Second?: any;
}

Note both the [x: number] and the readonly properties. This [x: number] property doesn't exist with a string enum.

But with in Enum, you can change the object:

enum MyEnum {
    First,  // default value of this is 0
    Second, // default value of this is 1
}

let obj: { [key in  MyEnum]?: any} = { [MyEnum.First]: 1 };
obj[MyEnum.First] = 1; // can use the enum...
obj[0] = 1;            // but can also use the enum value, 
                       // as it is a numeric enum by default

It's a numeric enum. But we can't use any number:

obj[42] = 1;
// Element implicitly has an 'any' type because 
// expression of type '42' can't be used to index type '{ 0?: any; 1?: any; }'.
// Property '42' does not exist on type '{ 0?: any; 1?: any; }'.

The declaration compiles to:

{
    0?: any;
    1?: any;
}

We allow only 0 and 1, the values of the enum.

This is in line with how you would expect an enum to work, there are no surprises unlike keyof typeof.

It works with string and heterogenous enums:

enum MyEnum
{
    First = 1,
    Second = "YES"
}

let obj: { [key in  MyEnum]?: any} = { [MyEnum.First]: 1, [MyEnum.Second]: 2 };
obj[1] = 0;
obj["YES"] = 0;

Here the type is:

{
    1?: any;
    YES?: any;
}

Get immutability with readonly:

let obj: { readonly [key in MyEnum]?: any} = { 
    [MyEnum.First]: 1,
};
obj[MyEnum.First] = 2;
// Cannot assign to '1' because it is a read-only property.

... which makes these keys readonly:

{
    readonly 1?: any;
    readonly 2?: any;
}

Summary

in Enum keyof typeof Enum
Compiles to enum values Compiles to enum keys
Does not allow values outside the enum Can allow numeric values outside the enum if you use a numeric enum
Can change the object, immutability opt-in with readonly Can't change enum props without -readonly. Other numeric values outside the enum can be

Use in Enum if possible.

2 of 6
140

Yes. Just type

let layer:{[key in keyof typeof MyEnum]: any}

The keyof keyword is available since Typescript 2.1. See the TypeScript documentation for more details. Using only keyof for enums wouldn't work (you'd get the keys of the enum type and not the enum constants), so you have to type keyof typeof.

Find elsewhere
🌐
Futurestud.io
futurestud.io › tutorials › typescript-using-a-string-as-enum-key
TypeScript — Using a String as Enum Key - Future Studio
February 1, 2024 - For indexed access, even with a “string-like” value, you must use one of the available keys. And you can create a union type of the available keys and use it to retrieve related values. You can define a union type of the keys manually or dynamically. Manually defining the keys creates a second place that you need to maintain in your code. The first place is the enum itself and the second is your type for the keys.
🌐
GitHub
github.com › colinhacks › zod › discussions › 839
Enum From Object Literal Keys · colinhacks/zod · Discussion #839
Very helpful thank you 🙏🏼 Is there currently a way to achieve the same for integers using z.enum or z.union with z.literal couldn't get it working so far. Not so ideal alternative might be to convert the integers to strings first, hmm 🤔 · Beta Was this translation helpful? Give feedback. ... There was an error while loading. Please reload this page. Something went wrong. There was an error while loading. Please reload this page. ... I was just having this issue. My simple fix was: const [firstKey, ...otherKeys] = Object.keys(MY_OBJECT) z.enum([firstKey, ...otherKeys]) // ...if that still throws an error, also try: z.enum([firstKey!, ...otherKeys])
Author   colinhacks
Top answer
1 of 16
557

TypeScript 2.4

Now has string enums so your code just works:

enum E {
    hello = "hello",
    world = "world"
};

TypeScript 1.8

Since TypeScript 1.8 you can use string literal types to provide a reliable and safe experience for named string values (which is partially what enums are used for).

type Options = "hello" | "world";
var foo: Options;
foo = "hello"; // Okay 
foo = "asdf"; // Error!

More : https://www.typescriptlang.org/docs/handbook/advanced-types.html#string-literal-types

Legacy Support

Enums in TypeScript are number based.

You can use a class with static members though:

class E
{
    static hello = "hello";
    static world = "world"; 
}

You could go plain as well:

var E = {
    hello: "hello",
    world: "world"
}

Update: Based on the requirement to be able to do something like var test:E = E.hello; the following satisfies this:

class E
{
    // boilerplate 
    constructor(public value:string){    
    }

    toString(){
        return this.value;
    }

    // values 
    static hello = new E("hello");
    static world = new E("world");
}

// Sample usage: 
var first:E = E.hello;
var second:E = E.world;
var third:E = E.hello;

console.log("First value is: "+ first);
console.log(first===third); 
2 of 16
127

In latest version (1.0RC) of TypeScript, you can use enums like this:

enum States {
    New,
    Active,
    Disabled
} 

// this will show message '0' which is number representation of enum member
alert(States.Active); 

// this will show message 'Disabled' as string representation of enum member
alert(States[States.Disabled]);

Update 1

To get number value of enum member from string value, you can use this:

var str = "Active";
// this will show message '1'
alert(States[str]);

Update 2

In latest TypeScript 2.4, there was introduced string enums, like this:

enum ActionType {
    AddUser = "ADD_USER",
    DeleteUser = "DELETE_USER",
    RenameUser = "RENAME_USER",

    // Aliases
    RemoveUser = DeleteUser,
}

For more info about TypeScript 2.4, read blog on MSDN.

🌐
DEV Community
dev.to › bwca › typing-object-keys-with-enum-values-using-typescript-4k23
Typing Object Keys With Enum Values Using Typescript - DEV Community
November 1, 2023 - interface Converter<A extends Array<unknown>, V> { <T>(keys: Array<T>, ...args: A): Record<string & T, V> } ... A an array of additional values, passed to the converted function, left as an array of unknown, since the interface does not really care about them; V the type for the values, the mapped object keys will be pointing, this will provide the flexibility, we do not impose any restrictions; T this is the enum type, which will be passed.
🌐
GitHub
github.com › Microsoft › TypeScript › issues › 14682
Use const enum values as keys of object literals · Issue #14682 · microsoft/TypeScript
March 16, 2017 - Awaiting More FeedbackThis means ... featureSuggestionAn idea for TypeScriptAn idea for TypeScript ... Compatibility Since JS supports string literals keys, and strings containing . is not a valid id, we may limit the usage of const enums to "EnumTypeName.EnumValueName" to avoid ...
Author   gdh1995
🌐
GitHub
github.com › UselessPickles › ts-enum-util › blob › master › docs › EnumWrapper.md
ts-enum-util/docs/EnumWrapper.md at master · UselessPickles/ts-enum-util
EnumWrapper is genericly typed based on the wrapped enum-like object with several method overloaded to ensure that params and results are as specifically-typed as possible. For example, when obtaining a key or keys from an EnumWrapper, the data type will be a string literal union containing only the specific key names that exist in the enum.
Author   UselessPickles
🌐
Futurestud.io
futurestud.io › tutorials › typescript-get-all-keys-of-an-enum
TypeScript — Get All Keys of an Enum - Future Studio
January 18, 2024 - Here’s an example of getting a list of enum keys in TypeScript using Object.keys(): export enum FutureStudioBooks { retrofit = 'Retrofit Book', picasso = 'Picasso Book', glide = 'Glide Book', gson = 'Gson Book', 'gson-workbook' = 'Gson Workbook', } const keys = Object.keys(FutureStudioBooks) // ['retrofit', 'picasso', 'glide', 'gson', 'gson-workbook'] The keys property now contains the enum’s keys as an array. A downside of using Object.keys() is that the resulting array has the string[] type:
🌐
Richinfante
richinfante.com › 2024 › 04 › 06 › ts-enum-record-required-keys
Typescript trick: Required enum values as keys
April 6, 2024 - Instead of Record<Key1|Key2, ... are exhaustively defined as members in our object: type EnumRecord<KeyType extends string, ValueType> = {[key in KeyType]: ValueType};...