Home > other >  Can an interface have an enumerated key?
Can an interface have an enumerated key?

Time:11-03

Say I have the following example:


interface Price {
  currency: string;
  value: number;
}

interface Product {
  priceRetail: Price;
  priceWholesale: Price;
  priceDiscount: Price;
}

Is it possible to abbreviate to something like this?

interface Product {
  [priceRetail, priceWholesale, priceDiscount]: Price;
}

CodePudding user response:

You can do it with mapped types (but be sure to read Amirhe's answer):

type Product = {
    [Key in "priceRetail" | "priceWholesale" | "priceDiscount"]: Price;
};

Playground link

It's awkward to combine with other properties have have different types, though. For instance, if you wanted an example property of type boolean in addition to those Price properties, you'd have to use an intersection type:

type Product = {
    [Key in "priceRetail" | "priceWholesale" | "priceDiscount"]: Price;
} & {
    example: boolean;
};

Playground link

...or in two steps with extends (which is basically intersection though conflicts are handled differently):

type ProductPrices = {
    [Key in "priceRetail" | "priceWholesale" | "priceDiscount"]: Price;
};
interface Product extends ProductPrices {
    example: boolean;
}

Playground link

CodePudding user response:

You can use a provided utility type in typescript named Record.

type Product = Record<"priceRetail" | "priceWholesale" | "priceDiscount", Price>;

More on type Record: Record<Keys, Type>

Constructs an object type whose property keys are Keys and whose property values are Type. This utility can be used to map the properties of a type to another type.

  • Related