diff --git a/program/services.py b/program/services.py
index 67a11456649ee474cf0536aa44ca66a91e1caab6..fd1e6406a808cdd0424f2492ecd2f8efd8ac1abc 100644
--- a/program/services.py
+++ b/program/services.py
@@ -20,7 +20,6 @@
 import copy
 from datetime import datetime, time, timedelta
 from itertools import pairwise
-from typing import TypedDict
 
 from dateutil.relativedelta import relativedelta
 from dateutil.rrule import rrule
@@ -42,67 +41,19 @@ from program.models import (
 )
 from program.serializers import ScheduleSerializer, TimeSlotSerializer
 from program.typing import (
+    Conflicts,
     DayScheduleEntry,
     NestedEpisode,
     NestedSchedule,
     NestedShow,
     NestedTimeslot,
+    ScheduleCreateUpdateData,
+    ScheduleData,
     TimerangeEntry,
 )
 from program.utils import parse_date, parse_datetime, parse_time
 
 
-class ScheduleData(TypedDict):
-    add_business_days_only: bool | None
-    add_days_no: int | None
-    by_weekday: int | None
-    default_playlist_id: int | None
-    dryrun: bool | None
-    end_time: str
-    first_date: str
-    id: int | None
-    is_repetition: bool | None
-    last_date: str | None
-    rrule_id: int
-    show_id: int | None
-    start_time: str
-
-
-class Collision(TypedDict):
-    end: str
-    timeslot_id: int
-    memo: str
-    note_id: int | None
-    playlist_id: int | None
-    schedule_id: int
-    show_id: int
-    show_name: str
-    start: str
-
-
-class ProjectedEntry(TypedDict):
-    collisions: list[Collision]
-    end: str
-    error: str | None
-    hash: str
-    solution_choices: set[str]
-    start: str
-
-
-class Conflicts(TypedDict):
-    notes: dict
-    playlists: dict
-    projected: list[ProjectedEntry]
-    solutions: dict[str, str]
-
-
-class ScheduleCreateUpdateData(TypedDict):
-    notes: dict
-    playlists: dict
-    schedule: ScheduleData
-    solutions: dict[str, str]
-
-
 def create_timeslot(start: str, end: str, schedule: Schedule) -> TimeSlot:
     """Creates and returns an unsaved timeslot with the given `start`, `end` and `schedule`."""
 
diff --git a/program/typing.py b/program/typing.py
index 0375987e713946493f0b7451d8a7f9b294e053d8..82ed61ea16316a276b8050d9ac5fc77a016df049 100644
--- a/program/typing.py
+++ b/program/typing.py
@@ -105,3 +105,59 @@ RadioImageRequirementsSettings = TypedDict(
         "show.logo": ImageRequirements,
     },
 )
+
+
+class Link(TypedDict):
+    type_id: int
+    url: str
+
+
+class ScheduleData(TypedDict):
+    add_business_days_only: bool | None
+    add_days_no: int | None
+    by_weekday: int | None
+    default_playlist_id: int | None
+    dryrun: bool | None
+    end_time: str
+    first_date: str
+    id: int | None
+    is_repetition: bool | None
+    last_date: str | None
+    rrule_id: int
+    show_id: int | None
+    start_time: str
+
+
+class Collision(TypedDict):
+    end: str
+    timeslot_id: int
+    memo: str
+    note_id: int | None
+    playlist_id: int | None
+    schedule_id: int
+    show_id: int
+    show_name: str
+    start: str
+
+
+class ProjectedEntry(TypedDict):
+    collisions: list[Collision]
+    end: str
+    error: str | None
+    hash: str
+    solution_choices: set[str]
+    start: str
+
+
+class Conflicts(TypedDict):
+    notes: dict
+    playlists: dict
+    projected: list[ProjectedEntry]
+    solutions: dict[str, str]
+
+
+class ScheduleCreateUpdateData(TypedDict):
+    notes: dict
+    playlists: dict
+    schedule: ScheduleData
+    solutions: dict[str, str]
diff --git a/program/utils.py b/program/utils.py
index ea2339091928af7c569746df3422306b07b4b59c..9ef4f22579cc4d65072c0ba6dbc7c9ca867c6c7f 100644
--- a/program/utils.py
+++ b/program/utils.py
@@ -21,12 +21,13 @@
 import json
 import typing
 from datetime import date, datetime, time
-from typing import Dict, Optional, Tuple, TypedDict, Union
+from typing import Dict, Optional, Tuple, Union
 
 import requests
 
 from django.conf import settings
 from django.utils import timezone
+from program.typing import Link
 
 if typing.TYPE_CHECKING:
     from program.models import Host, HostLink, Note, NoteLink, Show, ShowLink
@@ -34,11 +35,6 @@ else:
     from program.models import Host, HostLink, Note, NoteLink, Show, ShowLink
 
 
-class Link(TypedDict):
-    type_id: int
-    url: str
-
-
 def parse_datetime(date_string: str | None) -> datetime | None:
     """
     parse a datetime string and return a timezone aware datetime object.