-5

is it possible to assign a type like number[] to the enum members for example

const enum Size { Small:number[], Medium, Large };

if not why is it not possible since it is just a collection of constants

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

  • 2
    No, it is not possible and doesn't make any sense. – Behemoth Aug 28 '23 at 11:07
  • Even if this were possible presumably you'd be assigning a *particular* array of numbers to `Small`, not the *type* `number[]`. What array would you be assigning here? Assuming it's `[0, 1]`, then does [this approach](https://tsplay.dev/NBBYnN) meet your needs? It doesn't use `enum` at all, but `enum` is only really meant for specific use cases and your use case doesn't fit. If this fully addresses your question I'll write up an answer explaining; if not, what am I missing? Please comment to let me know how to proceed. – jcalz Aug 28 '23 at 14:14
  • yeah @jcalz thanks for the first approach am just new to typescript but your case worked well – ovuoba chidera Aug 29 '23 at 06:25

1 Answers1

0

TypeScript enums are only really meant to support a very particular set of use cases. The values are always string or number. If you want one of the values to be a number[], then you can't use an enum.

And you really don't need or want to use an enum anyway; you can write the desired object directly and use a const assertion to get the behavior you're describing:

const Size = {
    Small: [0, 1],
    Medium: 0,
    Large: 1
} as const;

/* const Size: {
    readonly Small: readonly [0, 1];
    readonly Medium: 0;
    readonly Large: 1;
} */

Now Size is an object known to have keys Small, Medium, and Large, and the values at those keys are known to be exactly the values you initialized it with. If you want to use Size as the name of a type corresponding to those values, you can do it with the technique from Is there a `valueof` similar to `keyof` in TypeScript? :

type Size = (typeof Size)[keyof typeof Size];
// type Size = 0 | 1 | readonly [0, 1]

So now you can write the same sort of code you'd write with a true enum, where Size is both a type name and a value name:

const x: Size = Size.Medium; // okay

There are other differences between this approach and a true enum, but you probably don't care about them. For example, a real enum acts as a namespace so that Size.Small is also the name of a type corresponding to typeof Size.Small. If you do somehow need this, you can write it out (but it's tedious):

namespace Size {
    export type Small = typeof Size.Small;
    export type Medium = typeof Size.Medium;
    export type Large = typeof Size.Large;
}
const y: Size.Medium = Size.Medium; // okay

As another example, enum types are meant to be nominal, so you can't mix and match them even if they have the same values:

enum Enum1 { A = 0, B = 1, C = 2 }
enum Enum2 { D = 0, E = 1, F = 2 }
const e: Enum1 = Enum2.D // error, even though it is the same as Enum1.A

But do you actually want that to be an error? Probably not, and if you do, there are ways around that too... but I won't belabor the point since it's even more tedious to do that.

Playground link to code

jcalz
  • 264,269
  • 27
  • 359
  • 360