Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 8cb8cd4

Browse files
authored
Conform more code to strictNullChecks (#10368
* Conform more code to `strictNullChecks` * Iterate
1 parent 05e3fb0 commit 8cb8cd4

24 files changed

+176
-157
lines changed

src/Modal.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,19 @@ export type ComponentType = React.ComponentType<{
3232
onFinished?(...args: any): void;
3333
}>;
3434

35+
type Defaultize<P, D> = P extends any
36+
? string extends keyof P
37+
? P
38+
: Pick<P, Exclude<keyof P, keyof D>> &
39+
Partial<Pick<P, Extract<keyof P, keyof D>>> &
40+
Partial<Pick<D, Exclude<keyof D, keyof P>>>
41+
: never;
42+
3543
// Generic type which returns the props of the Modal component with the onFinished being optional.
36-
export type ComponentProps<C extends ComponentType> = Omit<React.ComponentProps<C>, "onFinished"> &
44+
export type ComponentProps<C extends ComponentType> = Defaultize<
45+
Omit<React.ComponentProps<C>, "onFinished">,
46+
C["defaultProps"]
47+
> &
3748
Partial<Pick<React.ComponentProps<C>, "onFinished">>;
3849

3950
export interface IModal<C extends ComponentType> {

src/components/structures/RoomView.tsx

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,7 +1020,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
10201020
});
10211021
};
10221022

1023-
private onPageUnload = (event: BeforeUnloadEvent): string => {
1023+
private onPageUnload = (event: BeforeUnloadEvent): string | undefined => {
10241024
if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) {
10251025
return (event.returnValue = _t("You seem to be uploading files, are you sure you want to quit?"));
10261026
} else if (this.getCallForRoom() && this.state.callState !== "ended") {
@@ -1034,7 +1034,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
10341034
const action = getKeyBindingsManager().getRoomAction(ev);
10351035
switch (action) {
10361036
case KeyBindingAction.DismissReadMarker:
1037-
this.messagePanel.forgetReadMarker();
1037+
this.messagePanel?.forgetReadMarker();
10381038
this.jumpToLiveTimeline();
10391039
handled = true;
10401040
break;
@@ -1067,7 +1067,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
10671067

10681068
if (!roomId) return;
10691069
const call = this.getCallForRoom();
1070-
this.setState({ callState: call ? call.state : null });
1070+
this.setState({ callState: call?.state });
10711071
};
10721072

10731073
private onAction = async (payload: ActionPayload): Promise<void> => {
@@ -1087,7 +1087,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
10871087
ContentMessages.sharedInstance().sendContentListToRoom(
10881088
[payload.file],
10891089
this.state.room.roomId,
1090-
null,
1090+
undefined,
10911091
this.context.client,
10921092
);
10931093
break;
@@ -1117,7 +1117,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
11171117
if (!this.state.matrixClientIsReady) {
11181118
this.setState(
11191119
{
1120-
matrixClientIsReady: this.context.client?.isInitialSyncComplete(),
1120+
matrixClientIsReady: !!this.context.client?.isInitialSyncComplete(),
11211121
},
11221122
() => {
11231123
// send another "initial" RVS update to trigger peeking if needed
@@ -1137,7 +1137,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
11371137
case Action.EditEvent: {
11381138
// Quit early if we're trying to edit events in wrong rendering context
11391139
if (payload.timelineRenderingType !== this.state.timelineRenderingType) return;
1140-
const editState = payload.event ? new EditorStateTransfer(payload.event) : null;
1140+
const editState = payload.event ? new EditorStateTransfer(payload.event) : undefined;
11411141
this.setState({ editState }, () => {
11421142
if (payload.event) {
11431143
this.messagePanel?.scrollToEventIfNeeded(payload.event.getId());
@@ -1194,7 +1194,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
11941194

11951195
private onRoomTimeline = (
11961196
ev: MatrixEvent,
1197-
room: Room | null,
1197+
room: Room | undefined,
11981198
toStartOfTimeline: boolean,
11991199
removed: boolean,
12001200
data?: IRoomTimelineData,
@@ -1228,7 +1228,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
12281228
this.handleEffects(ev);
12291229
}
12301230

1231-
if (ev.getSender() !== this.context.client.credentials.userId) {
1231+
if (ev.getSender() !== this.context.client.getSafeUserId()) {
12321232
// update unread count when scrolled up
12331233
if (!this.state.search && this.state.atEndOfLiveTimeline) {
12341234
// no change
@@ -1325,7 +1325,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
13251325
};
13261326

13271327
private getRoomTombstone(room = this.state.room): MatrixEvent | undefined {
1328-
return room?.currentState.getStateEvents(EventType.RoomTombstone, "");
1328+
return room?.currentState.getStateEvents(EventType.RoomTombstone, "") ?? undefined;
13291329
}
13301330

13311331
private async calculateRecommendedVersion(room: Room): Promise<void> {
@@ -1336,7 +1336,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
13361336

13371337
private async loadMembersIfJoined(room: Room): Promise<void> {
13381338
// lazy load members if enabled
1339-
if (this.context.client.hasLazyLoadMembersEnabled()) {
1339+
if (this.context.client?.hasLazyLoadMembersEnabled()) {
13401340
if (room && room.getMyMembership() === "join") {
13411341
try {
13421342
await room.loadMembersIfNeeded();
@@ -1415,7 +1415,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
14151415
};
14161416

14171417
private async updateE2EStatus(room: Room): Promise<void> {
1418-
if (!this.context.client.isRoomEncrypted(room.roomId)) return;
1418+
if (!this.context.client?.isRoomEncrypted(room.roomId)) return;
14191419

14201420
// If crypto is not currently enabled, we aren't tracking devices at all,
14211421
// so we don't know what the answer is. Let's error on the safe side and show
@@ -2093,7 +2093,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
20932093
// We have successfully loaded this room, and are not previewing.
20942094
// Display the "normal" room view.
20952095

2096-
let activeCall = null;
2096+
let activeCall: MatrixCall | null = null;
20972097
{
20982098
// New block because this variable doesn't need to hang around for the rest of the function
20992099
const call = this.getCallForRoom();
@@ -2102,7 +2102,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
21022102
}
21032103
}
21042104

2105-
let statusBar;
2105+
let statusBar: JSX.Element | undefined;
21062106
let isStatusAreaExpanded = true;
21072107

21082108
if (ContentMessages.sharedInstance().getCurrentUploads().length > 0) {
@@ -2301,7 +2301,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
23012301
/>
23022302
);
23032303

2304-
let topUnreadMessagesBar = null;
2304+
let topUnreadMessagesBar: JSX.Element | undefined;
23052305
// Do not show TopUnreadMessagesBar if we have search results showing, it makes no sense
23062306
if (this.state.showTopUnreadMessagesBar && !this.state.search) {
23072307
topUnreadMessagesBar = (
@@ -2342,7 +2342,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
23422342

23432343
const showChatEffects = SettingsStore.getValue("showChatEffects");
23442344

2345-
let mainSplitBody: React.ReactFragment;
2345+
let mainSplitBody: JSX.Element | undefined;
23462346
let mainSplitContentClassName: string;
23472347
// Decide what to show in the main split
23482348
switch (this.state.mainSplitContentType) {
@@ -2396,10 +2396,10 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
23962396
const mainSplitContentClasses = classNames("mx_RoomView_body", mainSplitContentClassName);
23972397

23982398
let excludedRightPanelPhaseButtons = [RightPanelPhases.Timeline];
2399-
let onAppsClick = this.onAppsClick;
2400-
let onForgetClick = this.onForgetClick;
2401-
let onSearchClick = this.onSearchClick;
2402-
let onInviteClick = null;
2399+
let onAppsClick: (() => void) | null = this.onAppsClick;
2400+
let onForgetClick: (() => void) | null = this.onForgetClick;
2401+
let onSearchClick: (() => void) | null = this.onSearchClick;
2402+
let onInviteClick: (() => void) | null = null;
24032403
let viewingCall = false;
24042404

24052405
// Simplify the header for other main split types

src/components/structures/SpaceHierarchy.tsx

Lines changed: 29 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,9 @@ const Tile: React.FC<ITileProps> = ({
100100
children,
101101
}) => {
102102
const cli = useContext(MatrixClientContext);
103-
const [joinedRoom, setJoinedRoom] = useState<Room>(() => {
103+
const [joinedRoom, setJoinedRoom] = useState<Room | undefined>(() => {
104104
const cliRoom = cli.getRoom(room.room_id);
105-
return cliRoom?.getMyMembership() === "join" ? cliRoom : null;
105+
return cliRoom?.getMyMembership() === "join" ? cliRoom : undefined;
106106
});
107107
const joinedRoomName = useTypedEventEmitterState(joinedRoom, RoomEvent.Name, (room) => room?.name);
108108
const name =
@@ -264,9 +264,9 @@ const Tile: React.FC<ITileProps> = ({
264264
</React.Fragment>
265265
);
266266

267-
let childToggle: JSX.Element;
268-
let childSection: JSX.Element;
269-
let onKeyDown: KeyboardEventHandler;
267+
let childToggle: JSX.Element | undefined;
268+
let childSection: JSX.Element | undefined;
269+
let onKeyDown: KeyboardEventHandler | undefined;
270270
if (children) {
271271
// the chevron is purposefully a div rather than a button as it should be ignored for a11y
272272
childToggle = (
@@ -386,32 +386,28 @@ export const showRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st
386386
});
387387
};
388388

389-
export const joinRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: string): Promise<unknown> => {
389+
export const joinRoom = async (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: string): Promise<unknown> => {
390390
// Don't let the user view a room they won't be able to either peek or join:
391391
// fail earlier so they don't have to click back to the directory.
392392
if (cli.isGuest()) {
393393
defaultDispatcher.dispatch({ action: "require_registration" });
394394
return;
395395
}
396396

397-
const prom = cli.joinRoom(roomId, {
398-
viaServers: Array.from(hierarchy.viaMap.get(roomId) || []),
399-
});
400-
401-
prom.then(
402-
() => {
403-
defaultDispatcher.dispatch<JoinRoomReadyPayload>({
404-
action: Action.JoinRoomReady,
405-
roomId,
406-
metricsTrigger: "SpaceHierarchy",
407-
});
408-
},
409-
(err) => {
410-
SdkContextClass.instance.roomViewStore.showJoinRoomError(err, roomId);
411-
},
412-
);
397+
try {
398+
await cli.joinRoom(roomId, {
399+
viaServers: Array.from(hierarchy.viaMap.get(roomId) || []),
400+
});
401+
} catch (err) {
402+
SdkContextClass.instance.roomViewStore.showJoinRoomError(err, roomId);
403+
return;
404+
}
413405

414-
return prom;
406+
defaultDispatcher.dispatch<JoinRoomReadyPayload>({
407+
action: Action.JoinRoomReady,
408+
roomId,
409+
metricsTrigger: "SpaceHierarchy",
410+
});
415411
};
416412

417413
interface IHierarchyLevelProps {
@@ -433,7 +429,7 @@ export const toLocalRoom = (cli: MatrixClient, room: IHierarchyRoom, hierarchy:
433429
);
434430

435431
// Pick latest room that is actually part of the hierarchy
436-
let cliRoom = null;
432+
let cliRoom: Room | null = null;
437433
for (let idx = history.length - 1; idx >= 0; --idx) {
438434
if (hierarchy.roomMap.get(history[idx].roomId)) {
439435
cliRoom = history[idx];
@@ -448,7 +444,7 @@ export const toLocalRoom = (cli: MatrixClient, room: IHierarchyRoom, hierarchy:
448444
room_type: cliRoom.getType(),
449445
name: cliRoom.name,
450446
topic: cliRoom.currentState.getStateEvents(EventType.RoomTopic, "")?.getContent().topic,
451-
avatar_url: cliRoom.getMxcAvatarUrl(),
447+
avatar_url: cliRoom.getMxcAvatarUrl() ?? undefined,
452448
canonical_alias: cliRoom.getCanonicalAlias() ?? undefined,
453449
aliases: cliRoom.getAltAliases(),
454450
world_readable:
@@ -476,7 +472,7 @@ export const HierarchyLevel: React.FC<IHierarchyLevelProps> = ({
476472
}) => {
477473
const cli = useContext(MatrixClientContext);
478474
const space = cli.getRoom(root.room_id);
479-
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
475+
const hasPermissions = space?.currentState.maySendStateEvent(EventType.SpaceChild, cli.getSafeUserId());
480476

481477
const sortedChildren = sortBy(root.children_state, (ev) => {
482478
return getChildOrder(ev.content.order, ev.origin_server_ts, ev.state_key);
@@ -579,7 +575,7 @@ export const useRoomHierarchy = (
579575

580576
const loadMore = useCallback(
581577
async (pageSize?: number): Promise<void> => {
582-
if (hierarchy.loading || !hierarchy.canLoadMore || hierarchy.noSupport || error) return;
578+
if (!hierarchy || hierarchy.loading || !hierarchy.canLoadMore || hierarchy.noSupport || error) return;
583579
await hierarchy.load(pageSize).catch(setError);
584580
setRooms(hierarchy.rooms);
585581
},
@@ -673,7 +669,7 @@ const ManageButtons: React.FC<IManageButtonsProps> = ({ hierarchy, selected, set
673669
onClick={async (): Promise<void> => {
674670
setRemoving(true);
675671
try {
676-
const userId = cli.getUserId();
672+
const userId = cli.getSafeUserId();
677673
for (const [parentId, childId] of selectedRelations) {
678674
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, childId);
679675

@@ -759,7 +755,7 @@ const SpaceHierarchy: React.FC<IProps> = ({ space, initialText = "", showRoom, a
759755
const visited = new Set<string>();
760756
const queue = [...directMatches.map((r) => r.room_id)];
761757
while (queue.length) {
762-
const roomId = queue.pop();
758+
const roomId = queue.pop()!;
763759
visited.add(roomId);
764760
hierarchy.backRefs.get(roomId)?.forEach((parentId) => {
765761
if (!visited.has(parentId)) {
@@ -797,7 +793,7 @@ const SpaceHierarchy: React.FC<IProps> = ({ space, initialText = "", showRoom, a
797793
return;
798794
}
799795

800-
const parentSet = selected.get(parentId);
796+
const parentSet = selected.get(parentId)!;
801797
if (!parentSet.has(childId)) {
802798
setSelected(new Map(selected.set(parentId, new Set([...parentSet, childId]))));
803799
return;
@@ -816,9 +812,9 @@ const SpaceHierarchy: React.FC<IProps> = ({ space, initialText = "", showRoom, a
816812
} else {
817813
const hasPermissions =
818814
space?.getMyMembership() === "join" &&
819-
space.currentState.maySendStateEvent(EventType.SpaceChild, cli.getUserId());
815+
space.currentState.maySendStateEvent(EventType.SpaceChild, cli.getSafeUserId());
820816

821-
let results: JSX.Element;
817+
let results: JSX.Element | undefined;
822818
if (filteredRoomSet.size) {
823819
results = (
824820
<>
@@ -843,7 +839,7 @@ const SpaceHierarchy: React.FC<IProps> = ({ space, initialText = "", showRoom, a
843839
);
844840
}
845841

846-
let loader: JSX.Element;
842+
let loader: JSX.Element | undefined;
847843
if (hierarchy.canLoadMore) {
848844
loader = (
849845
<div ref={loaderRef}>

src/components/views/dialogs/BugReportDialog.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ interface IProps {
4343
interface IState {
4444
sendLogs: boolean;
4545
busy: boolean;
46-
err: string;
46+
err: string | null;
4747
issueUrl: string;
4848
text: string;
49-
progress: string;
49+
progress: string | null;
5050
downloadBusy: boolean;
51-
downloadProgress: string;
51+
downloadProgress: string | null;
5252
}
5353

5454
export default class BugReportDialog extends React.Component<IProps, IState> {
@@ -181,12 +181,12 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
181181
};
182182

183183
public render(): React.ReactNode {
184-
let error = null;
184+
let error: JSX.Element | undefined;
185185
if (this.state.err) {
186186
error = <div className="error">{this.state.err}</div>;
187187
}
188188

189-
let progress = null;
189+
let progress: JSX.Element | undefined;
190190
if (this.state.busy) {
191191
progress = (
192192
<div className="progress">
@@ -196,7 +196,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
196196
);
197197
}
198198

199-
let warning;
199+
let warning: JSX.Element | undefined;
200200
if (window.Modernizr && Object.values(window.Modernizr).some((support) => support === false)) {
201201
warning = (
202202
<p>

0 commit comments

Comments
 (0)