diff --git a/src/components/structures/FilePanel.tsx b/src/components/structures/FilePanel.tsx
index 21ef0c4f31..14380341d1 100644
--- a/src/components/structures/FilePanel.tsx
+++ b/src/components/structures/FilePanel.tsx
@@ -129,7 +129,7 @@ class FilePanel extends React.Component<IProps, IState> {
         }
     }
 
-    public async fetchFileEventsServer(room: Room): Promise<void> {
+    public async fetchFileEventsServer(room: Room): Promise<EventTimelineSet> {
         const client = MatrixClientPeg.get();
 
         const filter = new Filter(client.credentials.userId);
diff --git a/src/components/structures/TimelinePanel.tsx b/src/components/structures/TimelinePanel.tsx
index e4c7d15596..d7d3b33b3e 100644
--- a/src/components/structures/TimelinePanel.tsx
+++ b/src/components/structures/TimelinePanel.tsx
@@ -16,11 +16,13 @@ limitations under the License.
 
 import React, { createRef, ReactNode, SyntheticEvent } from 'react';
 import ReactDOM from "react-dom";
-import { Room } from "matrix-js-sdk/src/models/room";
+import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
 import { MatrixEvent } from "matrix-js-sdk/src/models/event";
-import { TimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
+import { EventTimelineSet } from "matrix-js-sdk/src/models/event-timeline-set";
 import { EventTimeline } from "matrix-js-sdk/src/models/event-timeline";
 import { TimelineWindow } from "matrix-js-sdk/src/timeline-window";
+import { EventType, RelationType } from 'matrix-js-sdk/src/@types/event';
+import { SyncState } from 'matrix-js-sdk/src/sync.api';
 
 import SettingsStore from "../../settings/SettingsStore";
 import { Layout } from "../../settings/Layout";
@@ -39,10 +41,8 @@ import { UIFeature } from "../../settings/UIFeature";
 import { replaceableComponent } from "../../utils/replaceableComponent";
 import { arrayFastClone } from "../../utils/arrays";
 import MessagePanel from "./MessagePanel";
-import { SyncState } from 'matrix-js-sdk/src/sync.api';
 import { IScrollState } from "./ScrollPanel";
 import { ActionPayload } from "../../dispatcher/payloads";
-import { EventType } from 'matrix-js-sdk/src/@types/event';
 import ResizeNotifier from "../../utils/ResizeNotifier";
 import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
 import Spinner from "../views/elements/Spinner";
@@ -65,7 +65,7 @@ interface IProps {
     // representing.  This may or may not have a room, depending on what it's
     // a timeline representing.  If it has a room, we maintain RRs etc for
     // that room.
-    timelineSet: TimelineSet;
+    timelineSet: EventTimelineSet;
     showReadReceipts?: boolean;
     // Enable managing RRs and RMs. These require the timelineSet to have a room.
     manageReadReceipts?: boolean;
@@ -579,7 +579,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
         });
     };
 
-    private onRoomTimelineReset = (room: Room, timelineSet: TimelineSet): void => {
+    private onRoomTimelineReset = (room: Room, timelineSet: EventTimelineSet): void => {
         if (timelineSet !== this.props.timelineSet) return;
 
         if (this.messagePanel.current && this.messagePanel.current.isAtBottom()) {
@@ -792,8 +792,8 @@ class TimelinePanel extends React.Component<IProps, IState> {
             // that sending an RR for the latest message will set our notif counter
             // to zero: it may not do this if we send an RR for somewhere before the end.
             if (this.isAtEndOfLiveTimeline()) {
-                this.props.timelineSet.room.setUnreadNotificationCount('total', 0);
-                this.props.timelineSet.room.setUnreadNotificationCount('highlight', 0);
+                this.props.timelineSet.room.setUnreadNotificationCount(NotificationCountType.Total, 0);
+                this.props.timelineSet.room.setUnreadNotificationCount(NotificationCountType.Highlight, 0);
                 dis.dispatch({
                     action: 'on_room_read',
                     roomId: this.props.timelineSet.room.roomId,
@@ -1416,7 +1416,11 @@ class TimelinePanel extends React.Component<IProps, IState> {
         });
     }
 
-    private getRelationsForEvent = (...args) => this.props.timelineSet.getRelationsForEvent(...args);
+    private getRelationsForEvent = (
+        eventId: string,
+        relationType: RelationType,
+        eventType: EventType | string,
+    ) => this.props.timelineSet.getRelationsForEvent(eventId, relationType, eventType);
 
     render() {
         // just show a spinner while the timeline loads.
diff --git a/src/indexing/EventIndex.ts b/src/indexing/EventIndex.ts
index 43b3de42ed..103a2f0809 100644
--- a/src/indexing/EventIndex.ts
+++ b/src/indexing/EventIndex.ts
@@ -16,7 +16,7 @@ limitations under the License.
 
 import { EventEmitter } from "events";
 import { RoomMember } from 'matrix-js-sdk/src/models/room-member';
-import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
+import { Direction, EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
 import { Room } from 'matrix-js-sdk/src/models/room';
 import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
 import { EventTimelineSet } from 'matrix-js-sdk/src/models/event-timeline-set';
@@ -109,7 +109,7 @@ export default class EventIndex extends EventEmitter {
         // our message crawler.
         await Promise.all(encryptedRooms.map(async (room) => {
             const timeline = room.getLiveTimeline();
-            const token = timeline.getPaginationToken("b");
+            const token = timeline.getPaginationToken(Direction.Backward);
 
             const backCheckpoint: ICrawlerCheckpoint = {
                 roomId: room.roomId,
@@ -371,7 +371,7 @@ export default class EventIndex extends EventEmitter {
         if (!room) return;
 
         const timeline = room.getLiveTimeline();
-        const token = timeline.getPaginationToken("b");
+        const token = timeline.getPaginationToken(Direction.Backward);
 
         if (!token) {
             // The room doesn't contain any tokens, meaning the live timeline