Sometimes you can’t specify your types just with the built-in types. In that case, you can us OptionalUnion, and List from the typing module to specify custom type combinations.

from typing import List, Union, Optional

class RecipeIngredient:
    def __init__(self, ingredient: Union[Ingredient, str], quantity, measurement: Optional[str]=None, condition=None):
    if isinstance(ingredient, Ingredient):
        self.ingredient = ingredient
    else:
        self.ingredient = Ingredient(ingredient)
    pass

class Recipe:
    def __init__(self, title: str):
        self.order: int
        self.title: str = title
        self.ingredients: List[RecipeIngredient] = []
        self.steps: List[ReceipeStep] = []
    pass

List[RecipeIngredient]
The list type lets you say that you want a list of items of a particular type.

Union[Ingredient, str]
Union lets you specify two or more valid types. In this case, a type of Ingredient or string.

Optional[str]
It specifies that a type optional.
This means the value can be one of the specified types or none.