5

I have a function:

public doSomethingWithEnum(enumType) {
   // Iterate over enum keys with Object.keys(enumType)
}

And I can use it like so:

export enum MyEnum { SomeEnumValue = 'SomeEnumValue', SomeOtherValue = 'SomeOtherValue' }

doSomethingWithEnum(MyEnum);

That's fine, it works. The problem is that I'd like a type on that parameter so I can pass it any enum. At the moment, it might aswell be :any which I think is far too open.

Is there any way of restricting/specifying the type of that parameter?

What I've Tried

I know it's possible to restrict this by listing known types e.g.:

doSomethingWithEnum(enumType: MyEnum | MyOtherEnum)

But I need it more scalable than that, I don't want to have to append a type every time a different consumer needs to call the service.

JᴀʏMᴇᴇ
  • 218
  • 2
  • 15
  • What do you want to restrict it to? I would have assumed `enumType: MyEnum` would be desired, but apparently you want something broader. How broad? – Nicholas Tower Mar 10 '20 at 14:57
  • Ideally, `enum` - I know that's not possible though. What is next best thing? Some type of dictionary, I was thinking. – JᴀʏMᴇᴇ Mar 10 '20 at 14:58
  • VS code actually attempted to infer a type for me, it came up with something like `[x: string]: string` but it wouldn't run (it wouldn't accept the enum) so it was not a type that could take an enum, but it's prompted my thinking into there being something else – JᴀʏMᴇᴇ Mar 10 '20 at 15:01
  • _Any enum_ = _any object_ so just `enumType: object` – Aleksey L. Mar 10 '20 at 15:03
  • @AlekseyL. - is `object` any more specific to an enum type than `any`? – JᴀʏMᴇᴇ Mar 10 '20 at 15:06
  • Yes https://www.typescriptlang.org/docs/handbook/basic-types.html – Aleksey L. Mar 10 '20 at 15:08
  • Does this answer your question? [Enum as Parameter in TypeScript](https://stackoverflow.com/questions/30774874/enum-as-parameter-in-typescript) – Aleksey L. Mar 10 '20 at 15:19

1 Answers1

3

Enums are basically objects with key/value pairs, where the value is either a string or a number. So if you want to make a function that accepts literally any enum you can do:

enum Example {
    foo,
    bar
};

const doSomethingWithEnum = (en: Record<string, string | number>) => {
    Object.keys(en).forEach(key => console.log(key));
}

doSomethingWithEnum(Example);

This does mean that you could construct a non-enum object with strings/numbers as its keys and pass that in too.

Nicholas Tower
  • 72,740
  • 7
  • 86
  • 98
  • 2
    Thanks for your answer Nicholas! I've just tried that and get the following error: `Argument of type 'typeof ExampleEnum' is not assignable to parameter of type 'Record'. Index signature is missing in type 'typeof ExampleEnum'.` – JᴀʏMᴇᴇ Mar 10 '20 at 15:08
  • (Note: I left out `| Number` since the enums I'm using are string values) – JᴀʏMᴇᴇ Mar 10 '20 at 15:09
  • Hmm, i tried out that code in the typescript playground before posting my answer and it didn't complain. What version of typescript are you using? (http://www.typescriptlang.org/play/?ssl=1&ssc=1&pln=10&pc=30#code/KYOwrgtgBAogHgQwgBwDbCgbwFBT1AMwHsiAaXfAIwQCdsBfAbm2wGMiQBnAFygBMiAZSIRg3ABYBLEAHMA6pIkxw0ALxQAFKABcUAErB2NPgB4eNaTNJRzlqAB8oKysBoA+AJRRVbrBTwA8pQAVobcAHQA1sAAnpxaIB7hxDQwCKziGtEx3r7sXETo4ahEMlmxHh7M9CwCwqISlgpKKhrwSGjAVUA) – Nicholas Tower Mar 10 '20 at 15:13
  • @JᴀʏMᴇᴇ so you should try with string enum and this will work https://www.typescriptlang.org/play/index.html#code/KYOwrgtgBAogHgQwgBwDbCgbwFBT1AMwHsioBeKAcmKMoBpd8AjBAJ3KpdfuwF8BubNgDGREAGcALlAAmRAMpEIwSQAsAliADmAdXVqY4aBQAUoAFxQASsFGsZAHimtNWulGeuAfAEpyXrEY8AHkmACtbSQA6AGtgAE9xMxAfKOJWGARhVRM4+P8oUQkidCjUIi1chJ8fQV4hOUVlNVc9AyMTeCQ0YFqgA – Aleksey L. Mar 10 '20 at 15:14
  • @NicholasTower it complains because JayMee removed `| number` and enum in your example has numbers as values – Aleksey L. Mar 10 '20 at 15:15
  • I've just added `| number` back in just in case, still the same error. – JᴀʏMᴇᴇ Mar 10 '20 at 15:17
  • Ah - it's a version thing. In your playground link drop the version 3.3.3 and you'll see. – JᴀʏMᴇᴇ Mar 10 '20 at 15:20
  • This, essentially, answers my question - although it's subject to a version I'm not currently using. Which is a shame, but still - it's the right answer. – JᴀʏMᴇᴇ Mar 10 '20 at 15:21