2
votes

Assuming I need to define the shape of an object, like:

const orange = {
   color: 'red',
   sweet: true,
   acidic: true,
   bitter: false
}

With the interface

interface Fruit {
   color: string,
   ?
}

Where unknown part (flavors) should be constrained (only below keys are allowed, not necessarily all of them) by the following enum:

enum Taste {
   ACIDIC = 'acidic',
   SWEET = 'sweet',
   BITTER = 'bitter'
}

With corresponding values of boolean type.

I could've defined some Record<Taste, boolean>, but how do I incorporate that into my target Fruit interface, when (to make things even more complicated) I cannot define Fruit as a type (instead of interface), since it extends Food interface?

1
Why not to include the flavors into the Fruit interface?Dorin Baba
@DorinBaba : consider I'm using flavors separately but still want to keep those 2 in sync.Q. Q. McAcka

1 Answers

1
votes

Typescript interfaces support multiple inheritance

You should be able to do


enum Taste {
   ACIDIC = 'acidic',
   SWEET = 'sweet',
   BITTER = 'bitter'
}

interface Food { /* props common to all foods */ } 

interface Fruit extends Food, Record<Taste, boolean> {
    color: string;
}

In the event that one of the properties of Record<Taste, boolean> conflicts with a property on Food (i.e they have incompatible types), TS will give a type error at compile time.

If you don't want to require that all of the Taste properties are present, you could have Fruit implement Partial<Record<Taste, boolean>> instead.