Let's say I want to model a Fruit Shop in Typescript: I have a union type of string literals:
type Fruit = "apple" | "banana" | "cherry"
I have a fruit shop with a price list and stock register:
interface FruitShop1 {
priceList: {
apple: number,
banana: number,
cherry: number
}
stock: {
apple: number,
banana: number,
cherry: number
}
}
Since I will want to add lots of fruit later and I don't want to duplicate the properties manually on the priceList
and stock
properties, so I modified the FruitShop1
interface to use a mapped types based off Fruit
:
interface FruitShop2 {
priceList: { [fruit in Fruit]: number }
stock: { [fruit in Fruit]: number }
}
I create my class implemeting FruitShop
:
class FruitShopImpl implements FruitShop2 {
priceList: { apple: number; banana: number; cherry: number; };
stock: { apple: number; banana: number; cherry: number; };
}
However, I need to initialize pricelist
and stock
. How do I do this?
What I'd like is for every property in priceList
be initialized to 1 and every property in stock
to be initialized to 0.
I've tried interating over every property in a constructor, but this produces errors I think because priceList
isn't initialized so it has no properties to iterate over. This feels like a chicken-and-egg catch-22 problem. Is there a solution, without manually initializing each property individually?
I've gone for a similar solution as suggested by @soffyo, but instead of using an array I'm using an enum backed by enums. Here's my code:
enum Fruits {
Apple = "apple",
Banana = "banana",
Cherry = "cherry"
}
interface IFruitShop {
prices: { [fruit in Fruits]: number }
stock: { [fruit in Fruits]: number }
}
class FruitShop implements IFruitShop {
prices: IFruitShop['prices'];
stock: IFruitShop['stock'];
constructor() {
this.prices = {} as { [fruit in Fruits]: number };
this.stock = {} as { [fruit in Fruits]: number };
Object.keys(Fruits).forEach(f => {
this.prices[f as Fruits] = 1;
this.stock[f as Fruits] = 0;
});
}
}
I think string enum could be an advantage for me in my actual project.