Home > Net >  How can a string constant be used as a computed identifier in a union type in TypeScript?
How can a string constant be used as a computed identifier in a union type in TypeScript?

Time:12-21

I have the following union type:

interface Cell {};

type CellInfo =
  | { Provisioned: Cell }
  | { Cloned: Cell };

Is there a way to use a computed property identifier instead of a string literal? E. g.

interface Cell {};

const PROVISIONED = "Provisioned";

type CellInfo =
  | { [PROVISIONED]: Cell }
  | { Cloned: Cell };

This works. Now I'd like to use an object or an enum instead of individual constants. Enums cannot be used for computed properties, but this doesn't work either:

interface Cell {};

const CELL_TYPE = {
    PROVISIONED: "Provisioned",
    CLONED: "CLONED",
};

type CellInfo =
  | { [CELL_TYPE.PROVISIONED]: Cell }
  | { [CELL_TYPE.CLONED]: Cell };

The computed property's error message is A computed property name in a type literal must refer to an expression whose type is a literal type or a 'unique symbol' type.(1170).

Why is that and how can I do it?

CodePudding user response:

You can also use an enum instead of the const

interface Cell {};

enum CellType {
  PROVISIONED = 'Provisioned',
  CLONED = 'Cloned'
}

type CellInfo =
  | { [CellType.PROVISIONED]: Cell }
  | { [CellType.CLONED]: Cell };

Playground

CodePudding user response:

There are 2 ways to do it, one already mentioned by @CRice, another one is do const assertion on individual properties, this is a more granular approach

interface Cell {};

const CELL_TYPE = {
    PROVISIONED: "Provisioned" as const,
    CLONED: "CLONED" as const,
};

type CellInfo =
  | { [CELL_TYPE.PROVISIONED]: Cell }
  | { [CELL_TYPE.CLONED]: Cell };

playground

  • Related