Conform more of the codebase to `strictNullChecks` (#11100)

pull/28217/head
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: 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 result: (JSX.Element | string)[] = [];
if (!message) return result;

View File

@ -626,7 +626,7 @@ async function setBotPower(
success: true,
});
} 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;
copied: boolean;
downloaded: boolean;
error?: string;
error?: boolean;
}
/*
@ -94,7 +94,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent<IProps, I
cli.deleteKeyBackupVersion(info.version);
}
this.setState({
error: e,
error: true,
});
}
};

View File

@ -220,7 +220,6 @@ export interface IRoomState {
showUrlPreview?: boolean;
e2eStatus?: E2EStatus;
rejecting?: boolean;
rejectError?: Error;
hasPinnedWidgets?: boolean;
mainSplitContentType?: MainSplitContentType;
// whether or not a spaces context switch brought us here,
@ -1680,7 +1679,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.setState({
rejecting: false,
rejectError: error,
});
},
);
@ -1714,7 +1712,6 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
this.setState({
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.
return new Promise((resolve) => window.setTimeout(resolve, 1))
.then(() => {
return this.props.onFillRequest(backwards);
return this.props.onFillRequest?.(backwards);
})
.finally(() => {
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,
// something has gone badly wrong and rather than causing a loop of
// undismissable dialogs, let's just give up.
if (eventId) {
if (eventId && this.props.timelineSet.room) {
onFinished = () => {
// go via the dispatcher so that the URL is updated
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: this.props.timelineSet.room.roomId,
room_id: this.props.timelineSet.room!.roomId,
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
// events when viewing historical messages, we get stuck in a loop
// 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
// 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) {
Modal.createDialog(ErrorDialog, {
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 });
return;

View File

@ -71,7 +71,7 @@ export const WidgetContextMenu: React.FC<IProps> = ({
} catch (err) {
logger.error("Failed to start livestream", err);
// 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, {
title: _t("Failed to start livestream"),
description: message,

View File

@ -160,7 +160,7 @@ export default class BugReportDialog extends React.Component<IProps, IState> {
if (!this.unmounted) {
this.setState({
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 { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { HTTPError, MatrixError } from "matrix-js-sdk/src/matrix";
import { _t } from "../../../languageHandler";
import ConfirmRedactDialog from "./ConfirmRedactDialog";
@ -62,7 +63,13 @@ export default class ConfirmAndWaitRedactDialog extends React.PureComponent<IPro
await this.props.redact();
this.props.onFinished(true);
} 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") {
this.setState({ redactionErrorCode: code });
} else {

View File

@ -75,7 +75,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
this.openRequest();
await request.accept();
} catch (err) {
logger.error(err.message);
logger.error(err);
}
}
};
@ -86,7 +86,7 @@ export default class MKeyVerificationRequest extends React.Component<IProps> {
try {
await request.cancel();
} 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 SettingsFlag from "../elements/SettingsFlag";
import SettingsFieldset from "../settings/SettingsFieldset";
import AccessibleButton from "../elements/AccessibleButton";
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
interface IProps {
room: Room;
}
export default class UrlPreviewSettings extends React.Component<IProps> {
private onClickUserSettings = (e: React.MouseEvent): void => {
private onClickUserSettings = (e: ButtonEvent): void => {
e.preventDefault();
e.stopPropagation();
dis.fire(Action.ViewUserSettings);

View File

@ -132,7 +132,7 @@ export default class BasicMessageEditor extends React.Component<IProps, IState>
private hasTextSelected = false;
private _isCaretAtEnd = false;
private lastCaret: DocumentOffset;
private lastCaret!: DocumentOffset;
private lastSelection: ReturnType<typeof cloneSelection> | null = null;
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);
Modal.createDialog(ErrorDialog, {
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(() => {
MatrixClientPeg.get = () => null;
MatrixClientPeg.safeGet = () => null;
MatrixClientPeg.safeGet = () => new MatrixClient({ baseUrl: "foobar" });
});
it("Returns the value for a disabled feature", () => {

View File

@ -208,8 +208,8 @@ describe("MessagePreviewStore", () => {
const preview = await store.getPreviewForRoom(room, DefaultTagID.Untagged);
expect(preview).toBeDefined();
expect(preview.isThreadReply).toBe(false);
expect(preview.text).toMatchInlineSnapshot(`"@sender:server reacted 🙃 to First message"`);
expect(preview?.isThreadReply).toBe(false);
expect(preview?.text).toMatchInlineSnapshot(`"@sender:server reacted 🙃 to First message"`);
});
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);
expect(preview).toBeDefined();
expect(preview.isThreadReply).toBe(false);
expect(preview.text).toContain("You reacted 🙃 to root event message");
expect(preview?.isThreadReply).toBe(false);
expect(preview?.text).toContain("You reacted 🙃 to root event message");
});
});