Nysithea
Nysithea

Reputation: 353

TypeScript template literal type parsing error

I'm trying to make type test become a union of the enum ModalTypes' values. According to the docs I should be able to write a type test like in the commented row. It seems to yield the correct type that I want, but it's giving me a compile error. If I write the union manually as shown in this picture, everything works as expected. What am I missing? Code snippet

Here is the error that I get Parsing error: Type expected. Although I don't get any squigglies in the code. Error

You can clearly see that test is becoming the string type union that I'm aiming for. But it's giving me the error above. Code snippet

Same code, in text...

export enum ModalTypes {
   USER = 'user',
   NOTE = 'note',
   REMINDER = 'reminder',
   CONTRACT = 'contract',
}

type test = `${ModalTypes}`;
// type test = 'user' | 'note' | 'reminder' | 'contract';
type req = {
    [key in test]: {
        try: string;
    };
};

Upvotes: 2

Views: 719

Answers (2)

Andrii Biletskyi
Andrii Biletskyi

Reputation: 165

Seems to me that it's some wrong settings in your linter.

Also, you can write this req type with usage of Record.

type req = Record<ModalTypes, { try: string }>

Upvotes: 1

Kelvin Schoofs
Kelvin Schoofs

Reputation: 8718

In your case, why not use something like:

// 'USER' | 'NOTE' | ...
type Key = keyof typeof ModalTypes;
// basically an alias for ModalTypes
type Value = (typeof ModalTypes)[Key];

It's worth mentioning that your ModalTypes "type" already represents the union of your enum values. Therefore Value is basically a convoluted alias for ModalTypes. That your enum type is already an union of its values can be seen here:

type Omitted = Exclude<Value, 'user'>;
// Mousing over the above gives the following hint in VS Code:
type Omitted = ModalTypes.NOTE | ModalTypes.REMINDER | ModalTypes.CONTRACT

Upvotes: 1

Related Questions