Conform more of the codebase to strictNullChecks (#11100)

This commit is contained in:
Michael Telatynski 2023-06-22 14:39:36 +01:00 committed by GitHub
parent 328db8fdfd
commit 7b3a4e556a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 30 additions and 26 deletions

View file

@ -466,7 +466,7 @@ const emojiToJsxSpan = (emoji: string, key: number): JSX.Element => (
*/ */
export function formatEmojis(message: string | undefined, isHtmlMessage?: false): JSX.Element[]; export function formatEmojis(message: string | undefined, isHtmlMessage?: false): JSX.Element[];
export function formatEmojis(message: string | undefined, isHtmlMessage: true): string[]; export function formatEmojis(message: string | undefined, isHtmlMessage: true): string[];
export function formatEmojis(message: string | undefined, isHtmlMessage: boolean): (JSX.Element | string)[] { export function formatEmojis(message: string | undefined, isHtmlMessage?: boolean): (JSX.Element | string)[] {
const emojiToSpan = isHtmlMessage ? emojiToHtmlSpan : emojiToJsxSpan; const emojiToSpan = isHtmlMessage ? emojiToHtmlSpan : emojiToJsxSpan;
const result: (JSX.Element | string)[] = []; const result: (JSX.Element | string)[] = [];
if (!message) return result; if (!message) return result;

View file

@ -626,7 +626,7 @@ async function setBotPower(
success: true, success: true,
}); });
} catch (err) { } catch (err) {
sendError(event, err.message ? err.message : _t("Failed to send request."), err); sendError(event, err instanceof Error ? err.message : _t("Failed to send request."), err);
} }
} }

View file

@ -42,7 +42,7 @@ interface IState {
passPhraseConfirm: string; passPhraseConfirm: string;
copied: boolean; copied: boolean;
downloaded: boolean; downloaded: boolean;
error?: string; error?: boolean;
} }
/* /*
@ -94,7 +94,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent<IProps, I
cli.deleteKeyBackupVersion(info.version); cli.deleteKeyBackupVersion(info.version);
} }
this.setState({ this.setState({
error: e, error: true,
}); });
} }
}; };

View file

@ -220,7 +220,6 @@ export interface IRoomState {
showUrlPreview?: boolean; showUrlPreview?: boolean;
e2eStatus?: E2EStatus; e2eStatus?: E2EStatus;
rejecting?: boolean; rejecting?: boolean;
rejectError?: Error;
hasPinnedWidgets?: boolean; hasPinnedWidgets?: boolean;
mainSplitContentType?: MainSplitContentType; mainSplitContentType?: MainSplitContentType;
// whether or not a spaces context switch brought us here, // whether or not a spaces context switch brought us here,
@ -1680,7 +1679,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.setState({ this.setState({
rejecting: false, rejecting: false,
rejectError: error,
}); });
}, },
); );
@ -1714,7 +1712,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.setState({ this.setState({
rejecting: false, rejecting: false,
rejectError: error,
}); });
} }
}; };

View file

@ -491,7 +491,7 @@ export default class ScrollPanel extends React.Component<IProps> {
// This would cause jumping to happen on Chrome/macOS. // This would cause jumping to happen on Chrome/macOS.
return new Promise((resolve) => window.setTimeout(resolve, 1)) return new Promise((resolve) => window.setTimeout(resolve, 1))
.then(() => { .then(() => {
return this.props.onFillRequest(backwards); return this.props.onFillRequest?.(backwards);
}) })
.finally(() => { .finally(() => {
this.pendingFillRequests[dir] = false; this.pendingFillRequests[dir] = false;

View file

@ -1623,12 +1623,12 @@ class TimelinePanel extends React.Component<IProps, IState> {
// dialog, let's jump to the end of the timeline. If we weren't, // dialog, let's jump to the end of the timeline. If we weren't,
// something has gone badly wrong and rather than causing a loop of // something has gone badly wrong and rather than causing a loop of
// undismissable dialogs, let's just give up. // undismissable dialogs, let's just give up.
if (eventId) { if (eventId && this.props.timelineSet.room) {
onFinished = () => { onFinished = () => {
// go via the dispatcher so that the URL is updated // go via the dispatcher so that the URL is updated
dis.dispatch<ViewRoomPayload>({ dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom, action: Action.ViewRoom,
room_id: this.props.timelineSet.room.roomId, room_id: this.props.timelineSet.room!.roomId,
metricsTrigger: undefined, // room doesn't change metricsTrigger: undefined, // room doesn't change
}); });
}; };
@ -2098,7 +2098,7 @@ class TimelinePanel extends React.Component<IProps, IState> {
// forwards, otherwise if somebody hits the bottom of the loaded // forwards, otherwise if somebody hits the bottom of the loaded
// events when viewing historical messages, we get stuck in a loop // events when viewing historical messages, we get stuck in a loop
// of paginating our way through the entire history of the room. // of paginating our way through the entire history of the room.
const stickyBottom = !this.timelineWindow.canPaginate(EventTimeline.FORWARDS); const stickyBottom = !this.timelineWindow?.canPaginate(EventTimeline.FORWARDS);
// If the state is PREPARED or CATCHUP, we're still waiting for the js-sdk to sync with // If the state is PREPARED or CATCHUP, we're still waiting for the js-sdk to sync with
// the HS and fetch the latest events, so we are effectively forward paginating. // the HS and fetch the latest events, so we are effectively forward paginating.

View file

@ -75,7 +75,7 @@ export default class UserView extends React.Component<IProps, IState> {
} catch (err) { } catch (err) {
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: _t("Could not load user profile"), title: _t("Could not load user profile"),
description: err && err.message ? err.message : _t("Operation failed"), description: err instanceof Error ? err.message : _t("Operation failed"),
}); });
this.setState({ loading: false }); this.setState({ loading: false });
return; return;

View file

@ -71,7 +71,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
} catch (err) { } catch (err) {
logger.error("Failed to start livestream", err); logger.error("Failed to start livestream", err);
// XXX: won't i18n well, but looks like widget api only support 'message'? // XXX: won't i18n well, but looks like widget api only support 'message'?
const message = err.message || _t("Unable to start audio streaming."); const message = err instanceof Error ? err.message : _t("Unable to start audio streaming.");
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: _t("Failed to start livestream"), title: _t("Failed to start livestream"),
description: message, description: message,

View file

@ -160,7 +160,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
if (!this.unmounted) { if (!this.unmounted) {
this.setState({ this.setState({
downloadBusy: false, downloadBusy: false,
downloadProgress: _t("Failed to send logs: ") + `${err.message}`, downloadProgress: _t("Failed to send logs: ") + `${err instanceof Error ? err.message : ""}`,
}); });
} }
} }

View file

@ -16,6 +16,7 @@ limitations under the License.
import React from "react"; import React from "react";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { HTTPError, MatrixError } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../languageHandler"; import { _t } from "../../../languageHandler";
import ConfirmRedactDialog from "./ConfirmRedactDialog"; import ConfirmRedactDialog from "./ConfirmRedactDialog";
@ -62,7 +63,13 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
await this.props.redact(); await this.props.redact();
this.props.onFinished(true); this.props.onFinished(true);
} catch (error) { } catch (error) {
const code = error.errcode || error.statusCode; let code: string | number | undefined;
if (error instanceof MatrixError) {
code = error.errcode;
} else if (error instanceof HTTPError) {
code = error.httpStatus;
}
if (typeof code !== "undefined") { if (typeof code !== "undefined") {
this.setState({ redactionErrorCode: code }); this.setState({ redactionErrorCode: code });
} else { } else {

View file

@ -75,7 +75,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
this.openRequest(); this.openRequest();
await request.accept(); await request.accept();
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err);
} }
} }
}; };
@ -86,7 +86,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
try { try {
await request.cancel(); await request.cancel();
} catch (err) { } catch (err) {
logger.error(err.message); logger.error(err);
} }
} }
}; };

View file

@ -28,14 +28,14 @@ import { Action } from "../../../dispatcher/actions";
import { SettingLevel } from "../../../settings/SettingLevel"; import { SettingLevel } from "../../../settings/SettingLevel";
import SettingsFlag from "../elements/SettingsFlag"; import SettingsFlag from "../elements/SettingsFlag";
import SettingsFieldset from "../settings/SettingsFieldset"; import SettingsFieldset from "../settings/SettingsFieldset";
import AccessibleButton from "../elements/AccessibleButton"; import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
interface IProps { interface IProps {
room: Room; room: Room;
} }
export default class UrlPreviewSettings extends React.Component<IProps> { export default class UrlPreviewSettings extends React.Component<IProps> {
private onClickUserSettings = (e: React.MouseEvent): void => { private onClickUserSettings = (e: ButtonEvent): void => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
dis.fire(Action.ViewUserSettings); dis.fire(Action.ViewUserSettings);

View file

@ -132,7 +132,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private hasTextSelected = false; private hasTextSelected = false;
private _isCaretAtEnd = false; private _isCaretAtEnd = false;
private lastCaret: DocumentOffset; private lastCaret!: DocumentOffset;
private lastSelection: ReturnType<typeof cloneSelection> | null = null; private lastSelection: ReturnType<typeof cloneSelection> | null = null;
private readonly useMarkdownHandle: string; private readonly useMarkdownHandle: string;

View file

@ -124,7 +124,7 @@ export default class ProfileSettings extends React.Component<{}, IState> {
logger.log("Failed to save profile", err); logger.log("Failed to save profile", err);
Modal.createDialog(ErrorDialog, { Modal.createDialog(ErrorDialog, {
title: _t("Failed to save your profile"), title: _t("Failed to save your profile"),
description: err && err.message ? err.message : _t("The operation could not be completed"), description: err instanceof Error ? err.message : _t("The operation could not be completed"),
}); });
} }

View file

@ -66,7 +66,7 @@ describe("DeviceSettingsHandler", () => {
afterEach(() => { afterEach(() => {
MatrixClientPeg.get = () => null; MatrixClientPeg.get = () => null;
MatrixClientPeg.safeGet = () => null; MatrixClientPeg.safeGet = () => new MatrixClient({ baseUrl: "foobar" });
}); });
it("Returns the value for a disabled feature", () => { it("Returns the value for a disabled feature", () => {

View file

@ -208,8 +208,8 @@ describe("MessagePreviewStore", () => {
const preview = await store.getPreviewForRoom(room, DefaultTagID.Untagged); const preview = await store.getPreviewForRoom(room, DefaultTagID.Untagged);
expect(preview).toBeDefined(); expect(preview).toBeDefined();
expect(preview.isThreadReply).toBe(false); expect(preview?.isThreadReply).toBe(false);
expect(preview.text).toMatchInlineSnapshot(`"@sender:server reacted 🙃 to First message"`); expect(preview?.text).toMatchInlineSnapshot(`"@sender:server reacted 🙃 to First message"`);
}); });
it("should generate the correct preview for a reaction on a thread root", async () => { it("should generate the correct preview for a reaction on a thread root", async () => {
@ -227,7 +227,7 @@ describe("MessagePreviewStore", () => {
const preview = await store.getPreviewForRoom(room, DefaultTagID.Untagged); const preview = await store.getPreviewForRoom(room, DefaultTagID.Untagged);
expect(preview).toBeDefined(); expect(preview).toBeDefined();
expect(preview.isThreadReply).toBe(false); expect(preview?.isThreadReply).toBe(false);
expect(preview.text).toContain("You reacted 🙃 to root event message"); expect(preview?.text).toContain("You reacted 🙃 to root event message");
}); });
}); });