0

I have this list of dishes:

const dishes = [
    {
      id: 'dish01',
      title: 'SALMON CRUNCH',
      price: 99,
      ingredients: [
        'SALMON',
        'CRUNCH SALAD',
      ],
      options: [
        {
          option: 'BASE',
          choices: ['RICE', 'SPAGHETTI', 'MIX'],
          defaultOption: 'MIX',
        },
      ],
    },
    {
      id: 'dish02',
      title: 'GOCHUJANG CHICKEN',
      price: 110,
      ingredients: [
        'GOCHUJANG',
        'CHICKEN',
      ],
      options: [
        {
          option: 'BASE',
          choices: ['RICE', 'SPAGHETTI', 'MIX'],
          defaultOption: 'MIX',
        },
        {
          option: 'TOPPING',
          choices: ['MAYO', 'KETCHUP', 'NONE'],
          defaultOption: 'NONE',
        },
      ],
    },
...
]

I then decide to use a useReducer (React) to keep track and build a single dish order object that goes into the card.

Is it then possible define a custom interface for each dish?

// types for dish01
type Ingredients = 'SALMON' | 'CRUNCH SALAD'

interface DishOrder {
  id: string
  withoutIngredients: Ingredients[]
  BASE: 'RICE' | 'SPAGHETTI' | 'MIX'
}

// types for dish02
type Ingredients = 'GOCHUJANG' | 'CHICKEN'

interface DishOrder {
  id: string
  withoutIngredients: Ingredients[]
  BASE: 'RICE' | 'SPAGHETTI' | 'MIX'
  TOPPINGS: 'MAYO' | 'KETCHUP' | 'NONE'
}

if not, is this then as typed as it can get:

interface DishOptions {
  [key: string]: string
}

// https://stackoverflow.com/a/45261035/618099
type DishOrder = DishOptions & {
  id: string
  withoutIngredients: string[]
}

2 Answers 2

2

Looks like a perfect case for generics?

type Ingredients = 'SALMON' | 'CRUNCH SALAD'

interface DishOrder<T> {
  id: string
  withoutIngredients: T[]
  BASE: 'RICE' | 'SPAGHETTI' | 'MIX'
  TOPPINGS: 'MAYO' | 'KETCHUP' | 'NONE'
}

// const yourDishOrder: DishOrder<Ingredients> = ...
Sign up to request clarification or add additional context in comments.

Comments

1

I would do it like this:

enum Ingredient {
  Salmon = "Salmon",
  CrunchSalad = "Crunch Salad",
  ...
}

enum Base {
  Ris = "Ris",
  ...
}

enum Topping {
  Mayo = "Mayo",
  ...
}

interface DishOrder {
  id: string;
  withoutIngredients: Ingredient[];
  toppings?: Topping[];
  base: Base[];
}

this is not an extreme case at all.

8 Comments

Thank you for this very quick reply and suggestion. It looks interesting and like a better approach than the last resort I suggested. Do the types have to be 'typed' or can I code something that declares the types?
It might not be an extreme case :D but I quickly go to the deeper end of pool instead of just staying longer in the "kiddie" pool.
I'm afraid they have to be typed. Unless you have an array of options somewhere
If I did then how would I then do it?
I think in such a case enums would not make much sense. I would suggest doing something like this: ``` const ingredientsOptionsArray = [...] as const; export type Ingredient = (typeof ingredientsOptionsArray)[number] ``` here's a similar example: typescriptlang.org/play?#code/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.