1
enum Foo {
  'Foo' = 'A',
  'Bar' = 'B'
}
type Value = `${Foo}` // 'A' | 'B'

I'm wondering why the enum type triggers the autodispatch feature in the template string type? Does anyone know what's going on here

Because the types allowed in the template string type are 'string | number | bigint | boolean | null | undefined' But does enum belong to one of these types? I try to get the keytype Key = keyof typeof Foo //'Foo' | 'Bar',This syntax proves that enums are more like objects,So why enums can be in template strings

leo
  • 47
  • 4
  • 1
    What do you mean by "autodispatch feature in the template string type"? What result would you have expected? – Robby Cornelissen Apr 03 '23 at 04:03
  • ``` type Res3 = 1 | 2 | 3 type IValue2 = `${Res3}` // '1' | '2' | '3' ``` For example, the above joint class will be automatically distributed in the model string – leo Apr 03 '23 at 05:40
  • Yes, unions are distributed in template literal types, but your question remains unclear. – Robby Cornelissen Apr 03 '23 at 05:53
  • I am very sorry that I may not have expressed it clearly, I re-edited the question – leo Apr 03 '23 at 07:02
  • You are confusing the *value* named `Res2` with the *type* named `Res2`. The value is the enum *object*; it exists at runtime; its type is `typeof Res2`, and you can't stringify it with template literal types (`\`${typeof Res2}\`` is an error). The type represents the union of the types of the enum *members*; they are strings or numbers (strings in your case). I'm inclined to close this as a duplicate of [the question answered here](https://stackoverflow.com/a/50396312/2887218). Please let me know as soon as possible if I've captured the essence of your issue or if I've missed it somehow. – jcalz Apr 03 '23 at 15:48
  • i want to express is why enum can be in template string, Thank you for answering my question – leo Apr 04 '23 at 03:15

1 Answers1

1

Enums are somewhat special, and there are a lot of subtle differences in both compile time and runtime behavior depending on whether the enum is numeric or string-based, and whether the enum members are constant or computed.

The TypeScript handbook notes:

When all members in an enum have literal enum values, some special semantics come into play.
[...] enum types themselves effectively become a union of each enum member.

This is why in the example below, the distributing behavior of the template literal type will yield the same results for EType and UType:

enum E { Foo = 'A', Bar = 'B' }
type EType = `${E}`; // "A" | "B"

type U = 'A' | 'B';
type UType = `${U}`; // "A" | "B"
Robby Cornelissen
  • 91,784
  • 22
  • 134
  • 156