Agata
Agata

Reputation: 13

typescript interface with a generic object parameter

I have multiple objects in my app. For example:

interface Recipe {  
  title: string,  
  ingredients: []  
  creator: string,  
  // ...  
}

interface Vendor {  
  name: string
  address: Address  
  // ...  
}

The user should have the ability to create objects that can accept any of these interfaces for example:

interface Event<T> {  
  date: Date(),  
  type: T // This should be of type Recipe or Vendor object for example.  
}
  1. What is the proper way to define this?
  2. How would I then find out which object the user passed?

Thank You!

Upvotes: 1

Views: 4352

Answers (1)

leonardfactory
leonardfactory

Reputation: 3501

In order to know which type the user passed, you need to use discriminated unions.

To do so, you should:

  1. Augment the interfaces adding a kind or type, or whatever you like, property in order to discriminate between them:
interface Recipe {  
  type: 'Recipe',
  title: string,  
  ingredients: []  
  creator: string,  
  // ...  
}

interface Vendor {  
  type: 'Vendor',
  name: string
  address: Address  
  // ...  
}
  1. Define an union type including the available objects
type Entity /* or whatever */ = Recipe | Vendor;

Now TS can understand which specific interface is used given the type property

  1. Define the Event given the union type
interface Event<T extends Entity> {  
  date: Date,  
  type: T['type'], // If you need only the type
  object?: T
}

const event: Event<Recipe> = {
  date: Date,
  type: 'recipe',
  object: recipe
}

function <T extends Entity>(event: Event<T>) {
  switch (event.type) {
    // ...
  }
}

Upvotes: 1

Related Questions